【问题标题】:Unable to see Set Test Message log value after test case marked as fail测试用例标记为失败后看不到设置测试消息日志值
【发布时间】:2020-12-15 14:33:18
【问题描述】:

我有以下代码:

*** Settings ***
Library     OperatingSystem
Library     Process
Library     String


*** Variables ***
@{MyList}=   item   items   items2
${LogStr1}   *HTML*

*** Test Cases *** 
#Start Test#
[xxxxx] My tests
    FOR  ${item}  IN   @{MyList}
        General                test.out         testProfile          ${item}
        [Template]    Run Test                                                                                                                                                         
        [Tags]    TestTags
    END

*** Keywords *** 
Run Test
    [Documentation]    Run the test
    [Arguments]       ${type}     ${profile}     ${file}    ${test}
            When suite config is updated 
            And updated the config in directory ${test}
            Then publish test status

suite config is updated
           [Documentation]    Get the variables list
            Log to Console     "Updating get suite config file"


updated the config in directory ${test}
    [Documentation]    Get the variables list 
         Run keyword if      "${test}" == "items"    Stop Test      "This is stop called"

publish test status 
    [Documentation]    Create and check if any issue found
            ${LogStr}=     Catenate     Test Passed : Log created:     <a href="Hello.txt">Hello</a>
            Log to Console       ${LogStr}
            ${LogStr1}=     Catenate         ${LogStr1}              ${LogStr}\n
            Set Test Variable    ${LogStr1}
            Set Test Message     ${LogStr1}

Stop Test  
    [Documentation]    Stop Execution 
    [Arguments]       ${FIALUREMSG}        
    Log To Console    ${FIALUREMSG}
    ${LogStr1}=     Catenate         ${LogStr1}              ${FIALUREMSG} 
      Fail        ${LogStr1}
  

根据代码,可以务实地使测试在第一次或第三次运行时失败。所以当我有这样的代码时:

Run keyword if      "${test}" == "item"    Stop Test      "This is stop called"

在提到的关键字中,有 2 个测试用例通过了一个套件但报告状态:

现在,如果我让第二个测试用例失败,我会得到以下测试消息日志:

Run keyword if      "${test}" == "items"    Stop Test      "This is stop called"

在提到的关键字中,有 2 个测试用例通过了一个套件但报告状态:

如果

 Run keyword if      "${test}" == "items2"    Stop Test      "This is stop called"

等等 - 因此,当测试用例标记为失败时,报告消息中似乎忽略了“设置测试消息”日志值。请注意,以下是我运行代码以将第一个测试用例标记为失败时的 log.html 内容:

Run keyword if      "${test}" == "item"    Stop Test      "This is stop called"

因此,我的所有问题是,如果我希望 report.html 文件显示所有失败和通过测试用例的日志,我该如何实现?

【问题讨论】:

  • @{MyList}的内容是否确定了runtime?
  • @BenceKaulics 不是上面代码中的静态值集

标签: robotframework


【解决方案1】:

如果您查看 Set Test Message 关键字的文档,它会说任何失败都会覆盖消息,但您可以选择从拆卸中覆盖失败消息。

在测试拆解中,此关键字可以更改可能的失败消息, 但否则失败会覆盖此关键字设置的消息。注意 在拆解中,消息可作为内置变量使用 ${TEST MESSAGE}.

因此,您可以做的不是调用 Set Test Message,而是将消息保存到测试变量中。然后您应该添加一个拆解,在其中调用 Set Test Message 并将您的测试变量与${TEST MESSAGE} 连接起来。例如:

*** Test Cases ***
Test
    [template]    Template
    [setup]    Set Test Variable    ${MSG}    ${EMPTY}    # create empty test variable to store messages
    1
    3
    2
    5
    6
    4
    6
    [teardown]    Set Test Message    ${MSG}\n${TEST MESSAGE}    # concatenate failure messages to normal test messages


*** Keywords ***
Template
    [arguments]    ${number}
    No Operation
    Run Keyword If    ${number} == 2    Fail      fail message ${number}
    Run Keyword If    ${number} == 4    Fail      fail message ${number}
    Set Test Variable    ${MSG}    ${MSG}\nMy test message ${number}    # concatenate next test message

此示例生成以下报告:

使用这种方法,您可以只在特定机器人套件中使用模板测试,因为测试用例表中列出的所有测试都将调用该模板。



其他完全不同的解决方案可以是摆脱FOR 循环,因为@{MyList} 中的元素是静态的。如果您将模板移动到Settings table,然后手动列出所有迭代,您可以将它们中的每一个分离成一个独立的测试用例。这样,一次迭代中的失败不会影响另一次迭代中的测试消息集。例如:

*** Settings ***
Test Template     Template

*** Test Cases ***
Test1    1
Test2    2
Test3    3
Test4    4
Test5    5
Test6    6


*** Keywords ***
Template
    [arguments]    ${number}
    No Operation
    Run Keyword If    ${number} == 2    Fail      fail message ${number}
    Run Keyword If    ${number} == 4    Fail      fail message ${number}
    Set Test Message    My test message ${number}

这将产生以下报告:

【讨论】:

    【解决方案2】:

    除了我的其他答案之外,您还有第三个选项,但它是一个更高级的解决方案,所以我决定将其作为单独的答案发布。

    您可以用 Python 编写一个小型测试库,该库也可以用作 listener。在这个监听器库中,您需要三个函数,其中两个是关键字,一个是监听器函数。

    1. 第一个函数是_log_message,在listener API 2 中有描述。如果发生任何日志记录,框架将调用此函数。因此,当测试失败时,此关键字将收到失败的日志条目,可以保存以备后用。此函数以_ 开头,在机器人套件中不能用作关键字。

      def _log_message(self, message):
          if message['level'] == 'FAIL':
              self.test_message = f"{self.test_message}\n{message['message']}"    # concatenate failure message
      
    2. 第二个函数add_test_message 将替换代码中的Set Test Message 关键字。其目的将类似,即附加要设置为测试消息的消息。这可以作为关键字从机器人套件中调用。

      def add_test_message(self, message):
          self.test_message = f"{self.test_message}\n{message}"    # concatenate normal test message
      
    3. 最后一个函数set_final_test_message 将为您设置实际的测试消息。必须在测试拆卸结束时调用此关键字,以确保没有其他故障会覆盖您的测试消息。它只是在内部调用 Set Test Message 关键字并设置由前两个函数创建的字符串。这可以作为关键字从机器人套件中调用。

      def set_final_test_message(self):
          """
          Call this keyword at the end of the test case teardown.
      
          This keyword can only be used in a test teardown.
          """
          BuiltIn()._get_test_in_teardown('Set Final Test Message')    # Check if we are in the test teardown, fail if not.
          BuiltIn().set_test_message(self.test_message)    # Call Set Test Message internally
      

    由于库的目的是设置测试消息,library scope 应该是TEST CASE。这意味着将在每个测试用例之前创建一个新的库对象,从而有效地重置先前测试设置的任何消息。

    这是整个库的代码(TestMessageLibrary.py):

    from robot.libraries.BuiltIn import BuiltIn
    
    class TestMessageLibrary(object):
        ROBOT_LIBRARY_SCOPE = 'TEST CASE'    # define library scope
        ROBOT_LISTENER_API_VERSION = 2    # select listener API
        ROBOT_LIBRARY_VERSION = 0.1
        
        def __init__(self):
            self.ROBOT_LIBRARY_LISTENER = self    # tell the framework that it will be a listener library
            self.test_message = ''    # internal variable to build the final test message
    
        def _log_message(self, message):
            if message['level'] == 'FAIL':
                self.test_message = f"{self.test_message}\n{message['message']}"    # concatenate failure message
        
        def add_test_message(self, message):
            self.test_message = f"{self.test_message}\n{message}"    # concatenate normal test message
    
        def set_final_test_message(self):
            """
            Call this keyword at the end of the test case teardown.
            
            This keyword can only be used in a test teardown.
            """
            BuiltIn()._get_test_in_teardown('Set Final Test Message')    # Check if we are in the test teardown, fail if not.
            BuiltIn().set_test_message(self.test_message)
            
    globals()[__name__] = TestMessageLibrary
    

    这是一个带有库的示例套件:

    *** Settings ***
    Library    TestMessageLibrary 
    
    *** Test Cases ***
    Test
        [template]    Template
        1
        3
        2
        5
        6
        4
        6
        [teardown]    Set Final Test Message
        
    Other Test
        Add Test Message    This should not conflict
        [teardown]    Set Final Test Message
    
    
    *** Keywords ***
    Template
        [arguments]    ${number}
        No Operation
        Run Keyword If    ${number} == 2    Fail      fail message ${number}
        Run Keyword If    ${number} == 4    Fail      fail message ${number}
        Add Test Message    My test message ${number}
    

    使用robot --pythonpath ./ SO.robot 调用的示例运行。由于该库与套件文件--pythonpath ./ 位于同一目录中,因此需要能够导入该库。

    报告文件:

    【讨论】:

    • 感谢您的详细解释-学习新功能很好
    猜你喜欢
    • 2017-02-21
    • 1970-01-01
    • 2013-01-19
    • 1970-01-01
    • 2022-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多