You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从Flask应用调用Robot Framework关键字报错RobotNotRunningError

解决Flask调用Robot Framework关键字时的RobotNotRunningError错误

问题背景

  • 环境:Robot Framework 5.0.1、Python 3.9
  • 现象:Python函数在Robot测试套件中调用正常,但通过Flask接口调用时,抛出RobotNotRunningError('Cannot access execution context')
  • 相关代码:
    Flask接口脚本:
    from flask import Flask, request
    from robot.libraries.BuiltIn import BuiltIn
    from robot.api.deco import keyword
    
    app = Flask(__name__)
    ...
    @app.get('/getAcctData') 
    def get_acctData():
        ROBOT_LISTENER_API_VERSION = 3
        ROBOT_LIBRARY_SCOPE = 'TEST SUITE'
        endPoint=  request.args.get('myKeyword') or 'get_defaultAcct'
        username = request.args.get('userid') or 'TEST_USER'
        password = request.args.get('password') or 'TEST_PW'
        BuiltIn().import_resource('/Users/S123/myProject/Tests/keywordsLibrary.robot')
        return(BuiltIn().run_keyword('endPoint',username, password)) 
    
    Robot关键字库keywordsLibrary.robot:
    *** Settings ***
    Library                 ${EXECDIR}/Libraries/robot_test_app.py 
    Library                 ${EXECDIR}/Libraries/basic.py 
    Library                 OperatingSystem
    Library                 RequestsLibrary
    Library                 Collections
    
    *** Variables ***
    ${ACCT_API_BASE_URL}=      https://acct-api-svc.saraTestOrg.com/api
    ${PAYLOADFile}=                ${EXECDIR}/TestData/acctRequests_payload.txt
    
    *** Keywords ***
    
    SaraSampleKeyword
        ${randomreturn}=    set variable    hello from Sara sample Keyword
        [return]   ${randomreturn}
    
    get_acct_api
    [Arguments]        ${API_ENDPOINT}   ${Client_ID}   ${Cleint_Secret}
    [Documentation]    call specific acct api end points 
     ------ some code here
    
  • 完整堆栈追踪:
    Traceback (most recent call last):
      File "/Users/S123/myProject/FlaskApp/app.py", line 22, in get_acctData
        BuiltIn().import_resource('/Users/S123/myProject/Tests/keywordsLibrary.robot')
      File "/usr/local/lib/python3.9/site-packages/robot/libraries/BuiltIn.py", line 722, in import_resource
        self._namespace.import_resource(path, self._variables)
      File "/usr/local/lib/python3.9/site-packages/robot/running/namespace.py", line 423, in import_resource
        self._import(resource, variables)
      File "/usr/local/lib/python3.9/site-packages/robot/running/namespace.py", line 436, in _import
        imported = importer.import_resource(source)
      File "/usr/local/lib/python3.9/site-packages/robot/running/importer.py", line 123, in import_resource
        return self._import_by_type(source, ResourceFile)
      File "/usr/local/lib/python3.9/site-packages/robot/running/importer.py", line 142, in _import_by_type
        return self._cached_import(source, lambda: self._import_from_source(source, type_))
      File "/usr/local/lib/python3.9/site-packages/robot/running/importer.py", line 162, in _cached_import
        imported = import_func()
      File "/usr/local/lib/python3.9/site-packages/robot/running/importer.py", line 142, in <lambda>
        return self._cached_import(source, lambda: self._import_from_source(source, type_))
      File "/usr/local/lib/python3.9/site-packages/robot/running/importer.py", line 169, in _import_from_source
        return type_(source, self._context).import_or_execute()
      File "/usr/local/lib/python3.9/site-packages/robot/running/resource.py", line 37, in __init__
        self.variables = self._create_variables()
      File "/usr/local/lib/python3.9/site-packages/robot/running/resource.py", line 61, in _create_variables
        return Variables(self.data.variables, self._context.variables)
      File "/usr/local/lib/python3.9/site-packages/robot/running/context.py", line 142, in variables
        return self._variables
      File "/usr/local/lib/python3.9/site-packages/robot/utils/robottypes.py", line 128, in __get__
        return instance.__dict__[self.name]
    KeyError: '_variables'
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2095, in __call__
        return self.wsgi_app(environ, start_response)
      File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2080, in wsgi_app
        response = self.handle_exception(e)
      File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2077, in wsgi_app
        response = self.full_dispatch_request()
      File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1525, in full_dispatch_request
        rv = self.handle_user_exception(e)
      File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1523, in full_dispatch_request
        rv = self.dispatch_request()
      File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1509, in dispatch_request
        return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
      File "/Users/S123/myProject/FlaskApp/app.py", line 23, in get_acctData
        return(BuiltIn().run_keyword('endPoint',username, password)) 
      File "/usr/local/lib/python3.9/site-packages/robot/libraries/BuiltIn.py", line 523, in run_keyword
        return self._namespace.run_keyword(name, args, kwargs)
      File "/usr/local/lib/python3.9/site-packages/robot/running/namespace.py", line 517, in run_keyword
        return self._run_keyword(self.get_keyword(name), args, kwargs)
      File "/usr/local/lib/python3.9/site-packages/robot/running/namespace.py", line 537, in _run_keyword
        return keyword.run(args, kwargs)
      File "/usr/local/lib/python3.9/site-packages/robot/running/keyword.py", line 109, in run
        return self._run(self._arguments.resolve(args, kwargs))
      File "/usr/local/lib/python3.9/site-packages/robot/running/userkeyword.py", line 144, in _run
        self._scope.start_keyword(self.name, args)
      File "/usr/local/lib/python3.9/site-packages/robot/running/context.py", line 96, in start_keyword
        self._listener.start_keyword(self._create_keyword_info(name, args))
      File "/usr/local/lib/python3.9/site-packages/robot/utils/robottypes.py", line 128, in __get__
        return instance.__dict__[self.name]
    KeyError: '_context'
    

错误原因

Robot Framework的BuiltIn库依赖Robot执行上下文,只有在Robot测试运行时才会初始化这个上下文。Flask是独立的Web服务,运行时没有启动Robot的执行环境,直接调用BuiltIn()会因为找不到执行上下文报错。

解决方案

方案1:通过Robot完整执行环境调用关键字

创建临时Robot测试用例,通过robot.run()启动完整Robot环境执行关键字,适合快速验证现有关键字逻辑:

from flask import Flask, request
import tempfile
import os
from robot import run

app = Flask(__name__)

@app.get('/getAcctData') 
def get_acctData():
    end_point = request.args.get('myKeyword') or 'get_defaultAcct'
    username = request.args.get('userid') or 'TEST_USER'
    password = request.args.get('password') or 'TEST_PW'
    
    # 生成临时Robot测试文件
    with tempfile.NamedTemporaryFile(mode='w', suffix='.robot', delete=False) as f:
        temp_test_path = f.name
        f.write(f"""
*** Settings ***
Resource    /Users/S123/myProject/Tests/keywordsLibrary.robot

*** Test Cases ***
Call Target Keyword
    ${result}=    {end_point}    {username}    {password}
    Log To Console    ${result}
""")
    
    # 运行Robot测试,关闭日志/报告输出以提升性能
    run(temp_test_path, output=None, log=None, report=None)
    
    # 清理临时文件
    os.unlink(temp_test_path)
    
    # 可根据实际需求从控制台输出或自定义存储方式提取关键字返回结果
    return f"关键字执行完成"

方案2:重构逻辑,脱离Robot依赖

将关键字中的业务逻辑提取到独立Python模块,Flask和Robot测试分别调用该模块,是长期维护的最优方案:

  1. 提取业务逻辑到acct_service.py:
# acct_service.py
def get_acct_data(api_endpoint, client_id, client_secret):
    # 原get_acct_api关键字中的业务代码,比如API调用、数据处理等
    return "处理后的账户数据"
  1. 修改Robot关键字库,调用Python模块:
*** Settings ***
Library    ${EXECDIR}/Libraries/acct_service.py
... 其他库保持不变

*** Keywords ***
get_acct_api
    [Arguments]    ${API_ENDPOINT}    ${Client_ID}    ${Cleint_Secret}
    [Documentation]    call specific acct api end points 
    ${result}=    get_acct_data    ${API_ENDPOINT}    ${Client_ID}    ${Cleint_Secret}
    [Return]    ${result}
  1. Flask接口直接调用业务模块:
from flask import Flask, request
from Libraries.acct_service import get_acct_data

app = Flask(__name__)

@app.get('/getAcctData') 
def get_acctData():
    end_point = request.args.get('myKeyword') or 'get_defaultAcct'
    username = request.args.get('userid') or 'TEST_USER'
    password = request.args.get('password') or 'TEST_PW'
    
    # 直接调用业务逻辑函数
    result = get_acct_data(end_point, username, password)
    return result

方案对比

  • 方案1:无需修改现有Robot关键字,快速验证,但启动Robot环境有性能开销,结果捕获需额外处理
  • 方案2:架构清晰、性能优异,便于后续维护,但需要重构现有关键字逻辑

内容的提问来源于stack exchange,提问作者Sarah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 04:00:00