我的自定义Robot Framework库中有一个以下示例关键字,该关键字使用Robot Framework的BuiltIn库使用参数在测试序列中调用另一个关键字:
# MyLibrary.py
from robot.libraries.BuiltIn import BuiltIn
class MyLibrary(object):
def run_a_keyword(self, keywordName):
builtinLib = BuiltIn().get_library_instance("BuiltIn")
parameters = ['hi', 'second param']
# Runs the keyword with the given parameters
builtinLib.run_keyword(keywordName, *parameters)
例如,我将运行以下简化测试,以通过测试错误来检查关键字是否具有属性:
*** Settings ***
Library MyLibrary.py
*** Test Cases ***
Test Case
Run A Keyword My Keyword
Run Keyword And Expect Error Keyword 'Another Keyword' expected 3 arguments, got 2. Run A Keyword Another Keyword
*** Keywords ***
My Keyword
[Arguments] ${arg1} ${arg2}
Log To Console Keyword Executed
Another Keyword
[Arguments] ${arg1} ${arg2} ${arg3}
Log To Console Keyword Executed
我希望这个测试用例能够通过,但是尽管我已经指出了预期的错误,但在第二步中,Run Keyword and Expect Error
测试用例失败了?
为此,我的解决方法是在关键字中捕获buildInLib的调用引发的异常,然后将其重新抛出,在此之后,使用Run Keyword And Expect Error
的测试序列可以正常工作:
def run_a_keyword(self, keywordName):
builtinLib = BuiltIn().get_library_instance("BuiltIn")
parameters = ['hi', 'second param']
try:
builtinLib.run_keyword(keywordName, *parameters)
except Exception as err:
raise Exception(err.message)
但是,我需要一个侦听器才能将错误传递给服务:
class MyListener(object):
ROBOT_LISTENER_API_VERSION = 2
ROBOT_LIBRARY_SCOPE = 'GLOBAL'
def __init__(self):
self.ROBOT_LIBRARY_LISTENER = self
def log_message(self, message):
level = message['level']
if level == 'FAIL':
send_the_error_to_somewhere(message['message'])
log_message
被调用两次(当调用内置函数时,当我引发新异常时)。这将导致相同的错误将被处理并记录两次,这不是我想要的。
所以:如何使用调用内置函数的关键字Run Keyword And Expect Error
仍然只能处理一次错误?
答案 0 :(得分:2)
首先,Run Keyword And Expect Error
不处理语法错误-请参阅其文档,在末尾清楚地指出该错误,以及also its implementation-此错误属于dont_continue
类别。
您正在将2个参数传递给具有3个必需参数的关键字,这显然是语法错误。
为什么log_message
被调用/存储两次错误?因为引发了两个异常-一个在RF的内置关键字中,然后在您自定义中重新引发时。框架在每个异常中都记录致命级别,因此您得到了2。
我想到的第一个解决方案是通过消息 content 本身与日志处理程序进行通信。
最理想的解决方案领域是修改异常,例如,向其添加具有设置值的属性“生产者”,并签入处理程序hasattr(err, 'producer')
,但是它不再有权访问该异常,只是到消息文本。
在错误消息前加上特殊标识符:
except Exception as err:
raise Exception("SPECIAL_IDENTIFIER:{}".format(err.message))
,然后仅在有条件的情况下将其发送到某处:
if level == 'FAIL' and message['message'].startswith('SPECIAL_IDENTIFIER:'):
# get rid of the special identifier prefix, and then
send_the_error_to_somewhere(message['message'])