Introduction

The Robot Framework is a generic Test automation framework for acceptance Testing and acceptance Test-driven development (ATDD).

It has easy-to-use tabular test data syntax and uses the keyword-driven testing approach.

Concepts

The Robot Framework modular architecture can be extended with bundled and custom Test libraries (Figure 1):

  • A Test suite consists of a file containing Test cases.
  • A directory containing these suite files creates a nested structure of test suites.

Figure 1 - Architecture

Robot is capable of generating a report for each execution in its specific XML format (xUnit) as well as HTML data formats.

The native Robot Framework XML format has a well-defined schema that represents the pattern in which the framework executes the keywords given in that particular Test suite.

Operations

Importing Robot Framework XML Reports

Each Robot Test case can be marked with a tag identifying the requirement being tested; it can also be a Test definition already present in Jira. Tagging a requirement in a Test case will create a link between the Test case and the requirement. Identifying a Test case with an Issue key tag will create a Test execution for the pre-existing Test (it does not create any new Test in this case).

It is important that the Requirements Issue types mapping is configured at the point of import; otherwise, no link will be created.

Below is a simplified example of a Robot Framework XML report. There are some nested Test suites, and one failed test marked with tags. The WEB-1 tag corresponds to an existing story you want to test, while WEB-3 is the Test Issue key which contains the Test definition.

Robot-Framework example Suite and Test Case source file
*** Settings ***
Documentation     A test suite with a single Gherkin style test.
Library         BuiltIn
Library         Selenium2Library
Test Teardown     Close Browser

*** Variables ***
${SERVER}         localhost:8080
${BROWSER}        chrome
${DELAY}          0.5
${LOGIN URL}      http://${SERVER}/login.jsp
${WELCOME URL}    http://${SERVER}/secure/Dashboard.jspa
 
 
*** Test Cases ***
Gherkin Valid Login
    [Tags]      WEB-1  WEB-3
    Given browser is opened to login page
    When user "admin" logs in with password "password123"
    Then welcome page should be open

 
 
*** Keywords ***
Browser is opened to login page
    Open browser to login page
 
Open Browser To Login Page
    Open Browser    ${LOGIN URL}    ${BROWSER}
    Maximize Browser Window
    Set Selenium Speed    ${DELAY}
    Login Page Should Be Open


User "${username}" logs in with password "${password}"
    Input username    ${username}
    Input password    ${password}
    Submit credentials
 
Input Username
    [Arguments]    ${username}
    Input Text    login-form-username    ${username}


Input Password
    [Arguments]    ${password}
    Input Text    login-form-password    ${password}
 
Welcome Page Should Be Open
    Location Should Be    ${WELCOME URL}
    Title Should Be    System Dashboard - Your Company JIRA
Robot-Framework example output XML
<?xml version="1.0" encoding="UTF-8"?>
<robot generated="20170220 14:18:54.562" generator="Robot 3.0.2 (Python 2.7.13 on win32)">
  <suite source="C:\Users\lmfv\Documents\Saco de Features\xray-1238\robot-example\robotframework-webdemo\login_tests" id="s1" name="Login Tests">
    <suite source="C:\Users\lmfv\Documents\Saco de Features\xray-1238\robot-example\robotframework-webdemo\login_tests\gherkin_login.robot" id="s1-s1" name="Gherkin Login">
      <test id="s1-s1-t1" name="Gherkin Valid Login">
        <kw name="Given browser is opened to login page">
          <kw name="Login Page Should Be Open" library="resource">
            <kw name="Title Should Be" library="Selenium2Library">
              <doc>Verifies that current page title equals `title`.</doc>
              <arguments>
                <arg>Log in - Your Company JIRA</arg>
              </arguments>
              <msg timestamp="20170220 14:19:07.693" level="INFO">Page title is 'Log in - Your Company JIRA'.</msg>
              <status status="PASS" endtime="20170220 14:19:07.693" starttime="20170220 14:19:07.158">
              </status>
            </kw>
            <status status="PASS" endtime="20170220 14:19:07.693" starttime="20170220 14:19:07.158">
            </status>
          </kw>
          <status status="PASS" endtime="20170220 14:19:07.693" starttime="20170220 14:18:55.937">
          </status>
        </kw>
        <kw name="When user &quot;admin&quot; logs in with password &quot;password123&quot;">
          <kw name="Input Username" library="resource">
            <arguments>
              <arg>${username}</arg>
            </arguments>
            <kw name="Input Text" library="Selenium2Library">
              <doc>Types the given `text` into text field identified by `locator`.</doc>
              <arguments>
                <arg>login-form-username</arg>
                <arg>${username}</arg>
              </arguments>
              <msg timestamp="20170220 14:19:07.696" level="INFO">Typing text 'admin' into text field 'login-form-username'</msg>
              <status status="PASS" endtime="20170220 14:19:09.314" starttime="20170220 14:19:07.696">
              </status>
            </kw>
            <status status="PASS" endtime="20170220 14:19:09.314" starttime="20170220 14:19:07.695">
            </status>
          </kw>
          <kw name="Input Password" library="resource">
            <arguments>
              <arg>${password}</arg>
            </arguments>
            <kw name="Input Text" library="Selenium2Library">
              <doc>Types the given `text` into text field identified by `locator`.</doc>
              <arguments>
                <arg>login-form-password</arg>
                <arg>${password}</arg>
              </arguments>
              <msg timestamp="20170220 14:19:09.316" level="INFO">Typing text 'password123' into text field 'login-form-password'</msg>
              <status status="PASS" endtime="20170220 14:19:10.956" starttime="20170220 14:19:09.316">
              </status>
            </kw>
            <status status="PASS" endtime="20170220 14:19:10.956" starttime="20170220 14:19:09.315">
            </status>
          </kw>
          <kw name="Submit Credentials" library="resource">
            <kw name="Click Button" library="Selenium2Library">
              <doc>Clicks a button identified by `locator`.</doc>
              <arguments>
                <arg>login-form-submit</arg>
              </arguments>
              <msg timestamp="20170220 14:19:10.958" level="INFO">Clicking button 'login-form-submit'.</msg>
              <status status="PASS" endtime="20170220 14:19:17.476" starttime="20170220 14:19:10.958">
              </status>
            </kw>
            <status status="PASS" endtime="20170220 14:19:17.477" starttime="20170220 14:19:10.957">
            </status>
          </kw>
          <status status="PASS" endtime="20170220 14:19:17.478" starttime="20170220 14:19:07.695">
          </status>
        </kw>
        <kw name="Then welcome page should be open" library="resource">
          <kw name="Location Should Be" library="Selenium2Library">
            <doc>Verifies that current URL is exactly `url`.</doc>
            <arguments>
              <arg>${WELCOME URL}</arg>
            </arguments>
            <kw name="Capture Page Screenshot" library="Selenium2Library">
              <doc>Takes a screenshot of the current page and embeds it into the log.</doc>
              <msg timestamp="20170220 14:19:18.702" html="yes" level="INFO">&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td colspan="3"&gt;&lt;a href="selenium-screenshot-1.png"&gt;&lt;img src="selenium-screenshot-1.png" width="800px"&gt;&lt;/a&gt;</msg>
              <status status="PASS" endtime="20170220 14:19:18.702" starttime="20170220 14:19:18.004">
              </status>
            </kw>
            <msg timestamp="20170220 14:19:18.705" level="FAIL">Location should have been 'http://localhost:8080/secure/Dashboard.jspa' but was 'http://localhost:8080/login.jsp'</msg>
            <status status="FAIL" endtime="20170220 14:19:18.705" starttime="20170220 14:19:17.483">
            </status>
          </kw>
          <status status="FAIL" endtime="20170220 14:19:18.706" starttime="20170220 14:19:17.481">
          </status>
        </kw>
        <kw type="teardown" name="Close Browser" library="Selenium2Library">
          <doc>Closes the current browser.</doc>
          <status status="PASS" endtime="20170220 14:19:22.382" starttime="20170220 14:19:18.707">
          </status>
        </kw>
        <tags>
          <tag>WEB-1</tag>
          <tag>WEB-3</tag>
        </tags>
        <status status="FAIL" endtime="20170220 14:19:22.383" critical="yes" starttime="20170220 14:18:55.936">Location should have been 'http://localhost:8080/secure/Dashboard.jspa' but was 'http://localhost:8080/login.jsp'</status>
      </test>
      <doc>A test suite with a single Gherkin style test.This test is functionally identical to the example invalid_login.robot file.</doc>
      <status status="FAIL" endtime="20170220 14:19:22.397" starttime="20170220 14:18:54.670">
      </status>
    </suite>
    <status status="FAIL" endtime="20170220 14:22:12.549" starttime="20170220 14:18:54.567">
    </status>
  </suite>
</robot>

Robot Framework v4.0 XML Reports

Starting from version 5.0.0, Xray supports output format from Robot Framework 4.0, including new features such as the SKIP status, native IF/ELSE, and nested control structures.

<?xml version="1.0" encoding="UTF-8"?>
<robot generator="Robot 4.0.1 (Python 3.9.5 on darwin)" generated="20210511 14:11:38.099" rpa="false" schemaversion="2">
    <suite id="s1" name="Demo" source="/Users/dpca/Downloads/robot40_outputxml_changes/demo.robot">
        <test id="s1-t1" name="Example using conditional statements">
            <if>
                <branch type="IF" condition="${var1} > 0">
                    <kw name="Sleep" library="BuiltIn">
                        <arg>1</arg>
                        <doc>Pauses the test executed for the given time.</doc>
                        <status status="NOT RUN" starttime="20210511 14:11:38.144" endtime="20210511 14:11:38.144"/>
                    </kw>
                    <status status="NOT RUN" starttime="20210511 14:11:38.144" endtime="20210511 14:11:38.144"/>
                </branch>
                <branch type="ELSE">
                    <kw name="Sleep" library="BuiltIn">
                        <arg>2</arg>
                        <doc>Pauses the test executed for the given time.</doc>
                        <msg timestamp="20210511 14:11:40.146" level="INFO">Slept 2 seconds</msg>
                        <status status="PASS" starttime="20210511 14:11:38.144" endtime="20210511 14:11:40.146"/>
                    </kw>
                    <status status="PASS" starttime="20210511 14:11:38.144" endtime="20210511 14:11:40.146"/>
                </branch>
                <status status="PASS" starttime="20210511 14:11:38.144" endtime="20210511 14:11:40.146"/>
            </if>
            <status status="PASS" starttime="20210511 14:11:38.143" endtime="20210511 14:11:40.146"/>
        </test>
        <test id="s1-t2" name="Example using nested for loops">
            <for flavor="IN">
                <var>${robot}</var>
                <value>@{ROBOTS}</value>
                <iter>
                    <var name="${robot}">Cortana</var>
                    <for flavor="IN">
                        <var>${dog}</var>
                        <value>@{DOGS}</value>
                        <iter>
                            <var name="${dog}">James</var>
                            <kw name="Log" library="BuiltIn">
                                <arg>${robot} ${dog}</arg>
                                <doc>Logs the given message with the given level.</doc>
                                <msg timestamp="20210511 14:11:40.148" level="INFO">Cortana James</msg>
                                <status status="PASS" starttime="20210511 14:11:40.148" endtime="20210511 14:11:40.148"/>
                            </kw>
                            <status status="PASS" starttime="20210511 14:11:40.148" endtime="20210511 14:11:40.148"/>
                        </iter>
                        <iter>
                            <var name="${dog}">Paul</var>
                            <kw name="Log" library="BuiltIn">
                                <arg>${robot} ${dog}</arg>
                                <doc>Logs the given message with the given level.</doc>
                                <msg timestamp="20210511 14:11:40.149" level="INFO">Cortana Paul</msg>
                                <status status="PASS" starttime="20210511 14:11:40.148" endtime="20210511 14:11:40.149"/>
                            </kw>
                            <status status="PASS" starttime="20210511 14:11:40.148" endtime="20210511 14:11:40.149"/>
                        </iter>
                        <status status="PASS" starttime="20210511 14:11:40.147" endtime="20210511 14:11:40.149"/>
                    </for>
                    <status status="PASS" starttime="20210511 14:11:40.147" endtime="20210511 14:11:40.149"/>
                </iter>
                <iter>
                    <var name="${robot}">Terminator</var>
                    <for flavor="IN">
                        <var>${dog}</var>
                        <value>@{DOGS}</value>
                        <iter>
                            <var name="${dog}">James</var>
                            <kw name="Log" library="BuiltIn">
                                <arg>${robot} ${dog}</arg>
                                <doc>Logs the given message with the given level.</doc>
                                <msg timestamp="20210511 14:11:40.150" level="INFO">Terminator James</msg>
                                <status status="PASS" starttime="20210511 14:11:40.149" endtime="20210511 14:11:40.150"/>
                            </kw>
                            <status status="PASS" starttime="20210511 14:11:40.149" endtime="20210511 14:11:40.150"/>
                        </iter>
                        <iter>
                            <var name="${dog}">Paul</var>
                            <kw name="Log" library="BuiltIn">
                                <arg>${robot} ${dog}</arg>
                                <doc>Logs the given message with the given level.</doc>
                                <msg timestamp="20210511 14:11:40.150" level="INFO">Terminator Paul</msg>
                                <status status="PASS" starttime="20210511 14:11:40.150" endtime="20210511 14:11:40.150"/>
                            </kw>
                            <status status="PASS" starttime="20210511 14:11:40.150" endtime="20210511 14:11:40.150"/>
                        </iter>
                        <status status="PASS" starttime="20210511 14:11:40.149" endtime="20210511 14:11:40.150"/>
                    </for>
                    <status status="PASS" starttime="20210511 14:11:40.149" endtime="20210511 14:11:40.150"/>
                </iter>
                <iter>
                    <var name="${robot}">AI</var>
                    <for flavor="IN">
                        <var>${dog}</var>
                        <value>@{DOGS}</value>
                        <iter>
                            <var name="${dog}">James</var>
                            <kw name="Log" library="BuiltIn">
                                <arg>${robot} ${dog}</arg>
                                <doc>Logs the given message with the given level.</doc>
                                <msg timestamp="20210511 14:11:40.151" level="INFO">AI James</msg>
                                <status status="PASS" starttime="20210511 14:11:40.151" endtime="20210511 14:11:40.151"/>
                            </kw>
                            <status status="PASS" starttime="20210511 14:11:40.150" endtime="20210511 14:11:40.151"/>
                        </iter>
                        <iter>
                            <var name="${dog}">Paul</var>
                            <kw name="Log" library="BuiltIn">
                                <arg>${robot} ${dog}</arg>
                                <doc>Logs the given message with the given level.</doc>
                                <msg timestamp="20210511 14:11:40.151" level="INFO">AI Paul</msg>
                                <status status="PASS" starttime="20210511 14:11:40.151" endtime="20210511 14:11:40.151"/>
                            </kw>
                            <status status="PASS" starttime="20210511 14:11:40.151" endtime="20210511 14:11:40.151"/>
                        </iter>
                        <status status="PASS" starttime="20210511 14:11:40.150" endtime="20210511 14:11:40.151"/>
                    </for>
                    <status status="PASS" starttime="20210511 14:11:40.150" endtime="20210511 14:11:40.151"/>
                </iter>
                <status status="PASS" starttime="20210511 14:11:40.147" endtime="20210511 14:11:40.151"/>
            </for>
            <status status="PASS" starttime="20210511 14:11:40.147" endtime="20210511 14:11:40.152"/>
        </test>
        <test id="s1-t3" name="This test will be skipped explictly">
            <kw name="Skip" library="BuiltIn">
                <doc>Skips the rest of the current test.</doc>
                <msg timestamp="20210511 14:11:40.152" level="SKIP">Skipped with Skip keyword.</msg>
                <status status="SKIP" starttime="20210511 14:11:40.152" endtime="20210511 14:11:40.153"/>
            </kw>
            <status status="SKIP" starttime="20210511 14:11:40.152" endtime="20210511 14:11:40.153">Skipped with Skip keyword.</status>
        </test>
        <test id="s1-t4" name="This test will always pass">
            <kw name="Pass Execution" library="BuiltIn">
                <arg>all good here</arg>
                <doc>Skips rest of the current test, setup, or teardown with PASS status.</doc>
                <msg timestamp="20210511 14:11:40.153" level="INFO">Execution passed with message:
all good here</msg>
                <status status="PASS" starttime="20210511 14:11:40.153" endtime="20210511 14:11:40.154"/>
            </kw>
            <status status="PASS" starttime="20210511 14:11:40.153" endtime="20210511 14:11:40.154">all good here</status>
        </test>
        <test id="s1-t5" name="This test will always fail">
            <kw name="Fail" library="BuiltIn">
                <arg>failed on purpose</arg>
                <doc>Fails the test with the given message and optionally alters its tags.</doc>
                <msg timestamp="20210511 14:11:40.154" level="FAIL">failed on purpose</msg>
                <status status="FAIL" starttime="20210511 14:11:40.154" endtime="20210511 14:11:40.154"/>
            </kw>
            <status status="FAIL" starttime="20210511 14:11:40.154" endtime="20210511 14:11:40.155">failed on purpose</status>
        </test>
        <test id="s1-t6" name="This test will also fail but will report as skip">
            <kw name="Fail" library="BuiltIn">
                <arg>failed also on purpose</arg>
                <doc>Fails the test with the given message and optionally alters its tags.</doc>
                <msg timestamp="20210511 14:11:40.156" level="FAIL">failed also on purpose</msg>
                <status status="FAIL" starttime="20210511 14:11:40.155" endtime="20210511 14:11:40.156"/>
            </kw>
            <tag>skipme</tag>
            <status status="SKIP" starttime="20210511 14:11:40.155" endtime="20210511 14:11:40.156">Test failed but its tags matched '--SkipOnFailure' and it was marked skipped.

Original failure:
failed also on purpose</status>
        </test>
        <test id="s1-t7" name="This test will fail due to the first kw, while 2nd one is marked as not run">
            <kw name="Fail" library="BuiltIn">
                <arg>failed on purpose</arg>
                <doc>Fails the test with the given message and optionally alters its tags.</doc>
                <msg timestamp="20210511 14:11:40.157" level="FAIL">failed on purpose</msg>
                <status status="FAIL" starttime="20210511 14:11:40.157" endtime="20210511 14:11:40.157"/>
            </kw>
            <kw name="Sleep" library="BuiltIn">
                <arg>1</arg>
                <doc>Pauses the test executed for the given time.</doc>
                <status status="NOT RUN" starttime="20210511 14:11:40.157" endtime="20210511 14:11:40.157"/>
            </kw>
            <status status="FAIL" starttime="20210511 14:11:40.156" endtime="20210511 14:11:40.157">failed on purpose</status>
        </test>
        <status status="FAIL" starttime="20210511 14:11:38.103" endtime="20210511 14:11:40.158"/>
    </suite>
    <statistics>
        <total>
            <stat pass="3" fail="2" skip="2">All Tests</stat>
        </total>
        <tag>
            <stat pass="0" fail="0" skip="1">skipme</stat>
        </tag>
        <suite>
            <stat pass="3" fail="2" skip="2" id="s1" name="Demo">Demo</stat>
        </suite>
    </statistics>
    <errors>
    </errors>
</robot>

Results in Xray Test Execution Page

Figure 2 - Results

Figure 3 - Results

Xray Integration with Robot Framework 5.0, 6.0 and 7.0

Starting from version 7.8.0, Xray fully supports the output format from Robot Framework 5.0, 6.0, and 7.0. These updates bring a range of new features and enhancements to streamline and optimize your test automation processes.

Key Features Implemented in Robot Framework 5.0

  • TRY/EXCEPT Syntax

    • Description: handles exceptions within your Test cases using TRY/EXCEPT blocks.
    • Benefits: allows for graceful error handling during Test execution, ensuring robust and reliable Test scripts.
  • WHILE Loops

    • Description: introduces WHILE loops, enabling the repetition of a set of steps while a condition is true.
    • Benefits: useful for dynamic scenarios where iterative execution is required until a specific condition is met.
  • Inline IF (Conditional Execution) 
    • Description: utilizes inline IF statements to conditionally execute keywords based on a condition.
    • Benefits: simplifies Test logic, making scripts more readable and maintainable.
  • Flow Control Keywords (RETURN, BREAK, and CONTINUE)

    • Description: controls the flow of execution within loops using new keywords.
        • RETURN: exits the current keyword.
        • BREAK: stops the loop.
        • CONTINUE: skips the current iteration and proceeds to the next one.
    • Benefits: provides greater control over test execution flow, allowing for more flexible and efficient test scripts.
Robot-Framework example Suite and Test Case source file
*** Settings ***
Documentation       Example test suite demonstrating Robot Framework v5 features

Library             Collections
Library             BuiltIn

*** Variables ***
${counter}      0

*** Test Cases ***
V5 Loop Example
    [Documentation]    Demonstrates WHILE loop
    ${counter}    Set Variable    0
    WHILE    ${counter} < 1
        Log    Counter value: ${counter}
        FOR    ${number}    IN    1    2
            IF    ${number} == 2
                TRY
                    Verify Stored Text Length    5     Hello
                EXCEPT    Database connection failed
                    Log To Console  Exception
                FINALLY
                    Log To Console  Finally
                END        
                BREAK
                Log to console    More than 1 item
            END
        END
        IF    ${counter} > 0   Log to console    More than 1 items    ELSE    Log to console    No Items.
        ${counter}    Evaluate    ${counter} + 1  
    END


*** Keywords ***
Verify Stored Text Length
    [Arguments]    ${expected_length}    ${text}
    Length Should Be    ${text}    ${expected_length}
    RETURN    ${text}
Robot-Framework 5.0 example output XML
<?xml version="1.0" encoding="UTF-8"?>
<robot generator="Robot 5.0.1 (Python 3.12.3 on darwin)" generated="20240729 15:58:55.569" rpa="false" schemaversion="3">
    <suite id="s1" name="Example1" source="/Users/andre.rodrigues/Desktop/robot/doc/v5/example1.robot">
        <test id="s1-t1" name="V5 Loop Example" line="11">
            <kw name="Set Variable" library="BuiltIn">
                <var>${counter}</var>
                <arg>0</arg>
                <doc>Returns the given values which can then be assigned to a variables.</doc>
                <msg timestamp="20240729 15:58:55.586" level="INFO">${counter} = 0</msg>
                <status status="PASS" starttime="20240729 15:58:55.586" endtime="20240729 15:58:55.586"/>
            </kw>
            <while condition="${counter} < 1">
                <iter>
                    <kw name="Log" library="BuiltIn">
                        <arg>Counter value: ${counter}</arg>
                        <doc>Logs the given message with the given level.</doc>
                        <msg timestamp="20240729 15:58:55.586" level="INFO">Counter value: 0</msg>
                        <status status="PASS" starttime="20240729 15:58:55.586" endtime="20240729 15:58:55.586"/>
                    </kw>
                    <for flavor="IN">
                        <var>${number}</var>
                        <value>1</value>
                        <value>2</value>
                        <iter>
                            <var name="${number}">1</var>
                            <if>
                                <branch type="IF" condition="${number} == 2">
                                    <try>
                                        <branch type="TRY">
                                            <kw name="Verify Stored Text Length">
                                                <arg>5</arg>
                                                <arg>Hello</arg>
                                                <status status="NOT RUN" starttime="20240729 15:58:55.586" endtime="20240729 15:58:55.586"/>
                                            </kw>
                                            <status status="NOT RUN" starttime="20240729 15:58:55.586" endtime="20240729 15:58:55.586"/>
                                        </branch>
                                        <branch type="EXCEPT">
                                            <pattern>Database connection failed</pattern>
                                            <kw name="Log To Console" library="BuiltIn">
                                                <arg>Exception</arg>
                                                <doc>Logs the given message to the console.</doc>
                                                <status status="NOT RUN" starttime="20240729 15:58:55.586" endtime="20240729 15:58:55.586"/>
                                            </kw>
                                            <status status="NOT RUN" starttime="20240729 15:58:55.586" endtime="20240729 15:58:55.586"/>
                                        </branch>
                                        <branch type="FINALLY">
                                            <kw name="Log To Console" library="BuiltIn">
                                                <arg>Finally</arg>
                                                <doc>Logs the given message to the console.</doc>
                                                <status status="NOT RUN" starttime="20240729 15:58:55.586" endtime="20240729 15:58:55.586"/>
                                            </kw>
                                            <status status="NOT RUN" starttime="20240729 15:58:55.586" endtime="20240729 15:58:55.586"/>
                                        </branch>
                                        <status status="NOT RUN" starttime="20240729 15:58:55.586" endtime="20240729 15:58:55.586"/>
                                    </try>
                                    <break>
                                        <status status="NOT RUN" starttime="20240729 15:58:55.586" endtime="20240729 15:58:55.586"/>
                                    </break>
                                    <kw name="Log To Console" library="BuiltIn">
                                        <arg>More than 1 item</arg>
                                        <doc>Logs the given message to the console.</doc>
                                        <status status="NOT RUN" starttime="20240729 15:58:55.586" endtime="20240729 15:58:55.586"/>
                                    </kw>
                                    <status status="NOT RUN" starttime="20240729 15:58:55.586" endtime="20240729 15:58:55.586"/>
                                </branch>
                                <status status="PASS" starttime="20240729 15:58:55.586" endtime="20240729 15:58:55.586"/>
                            </if>
                            <status status="PASS" starttime="20240729 15:58:55.586" endtime="20240729 15:58:55.586"/>
                        </iter>
                        <iter>
                            <var name="${number}">2</var>
                            <if>
                                <branch type="IF" condition="${number} == 2">
                                    <try>
                                        <branch type="TRY">
                                            <kw name="Verify Stored Text Length">
                                                <arg>5</arg>
                                                <arg>Hello</arg>
                                                <kw name="Length Should Be" library="BuiltIn">
                                                    <arg>${text}</arg>
                                                    <arg>${expected_length}</arg>
                                                    <doc>Verifies that the length of the given item is correct.</doc>
                                                    <msg timestamp="20240729 15:58:55.586" level="INFO">Length is 5</msg>
                                                    <status status="PASS" starttime="20240729 15:58:55.586" endtime="20240729 15:58:55.586"/>
                                                </kw>
                                                <return>
                                                    <value>${text}</value>
                                                    <status status="PASS" starttime="20240729 15:58:55.586" endtime="20240729 15:58:55.587"/>
                                                </return>
                                                <status status="PASS" starttime="20240729 15:58:55.586" endtime="20240729 15:58:55.587"/>
                                            </kw>
                                            <status status="PASS" starttime="20240729 15:58:55.586" endtime="20240729 15:58:55.587"/>
                                        </branch>
                                        <branch type="EXCEPT">
                                            <pattern>Database connection failed</pattern>
                                            <kw name="Log To Console" library="BuiltIn">
                                                <arg>Exception</arg>
                                                <doc>Logs the given message to the console.</doc>
                                                <status status="NOT RUN" starttime="20240729 15:58:55.587" endtime="20240729 15:58:55.587"/>
                                            </kw>
                                            <status status="NOT RUN" starttime="20240729 15:58:55.587" endtime="20240729 15:58:55.587"/>
                                        </branch>
                                        <branch type="FINALLY">
                                            <kw name="Log To Console" library="BuiltIn">
                                                <arg>Finally</arg>
                                                <doc>Logs the given message to the console.</doc>
                                                <status status="PASS" starttime="20240729 15:58:55.587" endtime="20240729 15:58:55.587"/>
                                            </kw>
                                            <status status="PASS" starttime="20240729 15:58:55.587" endtime="20240729 15:58:55.587"/>
                                        </branch>
                                        <status status="PASS" starttime="20240729 15:58:55.586" endtime="20240729 15:58:55.587"/>
                                    </try>
                                    <break>
                                        <status status="PASS" starttime="20240729 15:58:55.587" endtime="20240729 15:58:55.587"/>
                                    </break>
                                    <kw name="Log To Console" library="BuiltIn">
                                        <arg>More than 1 item</arg>
                                        <doc>Logs the given message to the console.</doc>
                                        <status status="NOT RUN" starttime="20240729 15:58:55.587" endtime="20240729 15:58:55.587"/>
                                    </kw>
                                    <status status="PASS" starttime="20240729 15:58:55.586" endtime="20240729 15:58:55.587"/>
                                </branch>
                                <status status="PASS" starttime="20240729 15:58:55.586" endtime="20240729 15:58:55.587"/>
                            </if>
                            <status status="PASS" starttime="20240729 15:58:55.586" endtime="20240729 15:58:55.587"/>
                        </iter>
                        <status status="PASS" starttime="20240729 15:58:55.586" endtime="20240729 15:58:55.587"/>
                    </for>
                    <if>
                        <branch type="IF" condition="${counter} > 0">
                            <kw name="Log To Console" library="BuiltIn">
                                <arg>More than 1 items</arg>
                                <doc>Logs the given message to the console.</doc>
                                <status status="NOT RUN" starttime="20240729 15:58:55.587" endtime="20240729 15:58:55.587"/>
                            </kw>
                            <status status="NOT RUN" starttime="20240729 15:58:55.587" endtime="20240729 15:58:55.587"/>
                        </branch>
                        <branch type="ELSE">
                            <kw name="Log To Console" library="BuiltIn">
                                <arg>No Items.</arg>
                                <doc>Logs the given message to the console.</doc>
                                <status status="PASS" starttime="20240729 15:58:55.587" endtime="20240729 15:58:55.587"/>
                            </kw>
                            <status status="PASS" starttime="20240729 15:58:55.587" endtime="20240729 15:58:55.587"/>
                        </branch>
                        <status status="PASS" starttime="20240729 15:58:55.587" endtime="20240729 15:58:55.587"/>
                    </if>
                    <kw name="Evaluate" library="BuiltIn">
                        <var>${counter}</var>
                        <arg>${counter} + 1</arg>
                        <doc>Evaluates the given expression in Python and returns the result.</doc>
                        <msg timestamp="20240729 15:58:55.587" level="INFO">${counter} = 1</msg>
                        <status status="PASS" starttime="20240729 15:58:55.587" endtime="20240729 15:58:55.587"/>
                    </kw>
                    <status status="PASS" starttime="20240729 15:58:55.586" endtime="20240729 15:58:55.587"/>
                </iter>
                <status status="PASS" starttime="20240729 15:58:55.586" endtime="20240729 15:58:55.587"/>
            </while>
            <doc>Demonstrates WHILE loop</doc>
            <status status="PASS" starttime="20240729 15:58:55.585" endtime="20240729 15:58:55.587"/>
        </test>
        <doc>Example test suite demonstrating Robot Framework v5 features</doc>
        <status status="PASS" starttime="20240729 15:58:55.569" endtime="20240729 15:58:55.587"/>
    </suite>
    <statistics>
        <total>
            <stat pass="1" fail="0" skip="0">All Tests</stat>
        </total>
        <tag>
        </tag>
        <suite>
            <stat pass="1" fail="0" skip="0" id="s1" name="Example1">Example1</stat>
        </suite>
    </statistics>
    <errors>
    </errors>
</robot>

Results in Xray Test Execution Page

Figure 4 - Results

Key Features Implemented in Robot Framework 6.0

Error Tag

  • Description: automatically adds an Error tag to Test cases that fail due to errors (as opposed to failures due to assertion errors).
  • Benefits: helps distinguish between different types of Test failures, making it easier to identify and address Issues.
Robot-Framework example Suite and Test Case source file
*** Test Cases ***
Invalid BREAK usage
    [Documentation]    BREAK and CONTINUE can only be used in the loop body,
    ...                not in keywords used in the loop.
    FOR    ${var}    IN    one    two    three
        Invalid BREAK
    END

*** Keywords ***
Invalid BREAK
    [Documentation]    This keyword fails due to invalid syntax.
    BREAK
Robot-Framework 6.0 example output XML
<?xml version="1.0" encoding="UTF-8"?>
<robot generator="Robot 6.1.1 (Python 3.12.3 on darwin)" generated="20240509 16:05:11.820"
    rpa="false" schemaversion="4">
    <suite id="s1" name="forBreakContinueTryExcept"
        source="/Users/andre.rodrigues/Desktop/robot/AIT/V6/forBreakContinueTryExcept.robot">
        <test id="s1-t1" name="Invalid BREAK usage" line="2">
            <for flavor="IN">
                <var>${var}</var>
                <value>one</value>
                <value>two</value>
                <value>three</value>
                <iter>
                    <var name="${var}">one</var>
                    <kw name="Invalid BREAK">
                        <doc>This keyword fails due to invalid syntax.</doc>
                        <error>
                            <value>BREAK</value>
                            <msg timestamp="20240509 16:05:11.834" level="FAIL">BREAK is not allowed
                                in this context.</msg>
                            <status status="FAIL" starttime="20240509 16:05:11.834"
                                endtime="20240509 16:05:11.834" />
                        </error>
                        <status status="FAIL" starttime="20240509 16:05:11.834"
                            endtime="20240509 16:05:11.834" />
                    </kw>
                    <status status="FAIL" starttime="20240509 16:05:11.834"
                        endtime="20240509 16:05:11.834" />
                </iter>
                <status status="FAIL" starttime="20240509 16:05:11.834"
                    endtime="20240509 16:05:11.834" />
            </for>
            <doc>BREAK and CONTINUE can only be used in the loop body,
                not in keywords used in the loop.</doc>
            <status status="FAIL" starttime="20240509 16:05:11.834" endtime="20240509 16:05:11.834">BREAK
                is not allowed in this context.</status>
        </test>
        <status status="FAIL" starttime="20240509 16:05:11.821" endtime="20240509 16:05:11.835" />
    </suite>
    <statistics>
        <total>
            <stat pass="0" fail="1" skip="0">All Tests</stat>
        </total>
        <tag>
</tag>
        <suite>
            <stat pass="0" fail="1" skip="0" id="s1" name="forBreakContinueTryExcept">
                forBreakContinueTryExcept</stat>
        </suite>
    </statistics>
    <errors>
</errors>
</robot>

Results in Xray Test Execution Page

Figure 5 - Results

Key Features Implemented in Robot Framework 7.0

Native VAR Syntax for Variables

  • Description: Robot Framework supports a native syntax for creating variables using the VAR keyword.
  • Benefits: simplifies variable creation and improves readability.
Robot-Framework example Suite and Test Case source file
*** Settings ***
Library    String
Library    Collections
Library    DateTime

*** Test Cases ***
IF/ELSE example
    IF    "${ENV}" == "devel"
        VAR    ${address}    127.0.0.1
        VAR    ${name}       demo
    ELSE
        VAR    ${address}    192.168.1.42
        VAR    ${name}       robot
    END
Robot-Framework 7.0 example output XML
<?xml version="1.0" encoding="UTF-8"?>
<robot generator="Robot 7.0 (Python 3.12.3 on darwin)" generated="2024-05-09T16:19:17.750789"
    rpa="false" schemaversion="5">
    <suite id="s1" name="exampleV7"
        source="/Users/andre.rodrigues/Desktop/robot/AIT/V7/exampleV7.robot">
        <test id="s1-t1" name="IF/ELSE example" line="7">
            <if>
                <branch type="IF" condition=""${ENV}" == "devel"">
                    <variable name="${address}">
                        <var>127.0.0.1</var>
                        <status status="NOT RUN" start="2024-05-09T16:19:17.778281"
                            elapsed="0.000015" />
                    </variable>
                    <variable name="${name}">
                        <var>demo</var>
                        <status status="NOT RUN" start="2024-05-09T16:19:17.778346"
                            elapsed="0.000008" />
                    </variable>
                    <msg time="2024-05-09T16:19:17.778375" level="FAIL">Invalid IF condition:
                        Evaluating expression '"${ENV}" == "devel"' failed: Variable '${ENV}' not
                        found.</msg>
                    <status status="FAIL" start="2024-05-09T16:19:17.777949" elapsed="0.000451">Invalid
                        IF condition: Evaluating expression '"${ENV}" == "devel"' failed: Variable
                        '${ENV}' not found.</status>
                </branch>
                <branch type="ELSE">
                    <variable name="${address}">
                        <var>192.168.1.42</var>
                        <status status="NOT RUN" start="2024-05-09T16:19:17.778431"
                            elapsed="0.000006" />
                    </variable>
                    <variable name="${name}">
                        <var>robot</var>
                        <status status="NOT RUN" start="2024-05-09T16:19:17.778450"
                            elapsed="0.000005" />
                    </variable>
                    <status status="NOT RUN" start="2024-05-09T16:19:17.778414" elapsed="0.000050" />
                </branch>
                <status status="FAIL" start="2024-05-09T16:19:17.777928" elapsed="0.000546">Invalid
                    IF condition: Evaluating expression '"${ENV}" == "devel"' failed: Variable
                    '${ENV}' not found.</status>
            </if>
            <status status="FAIL" start="2024-05-09T16:19:17.777771" elapsed="0.000806">Invalid IF
                condition: Evaluating expression '"${ENV}" == "devel"' failed: Variable '${ENV}' not
                found.</status>
        </test>
        <status status="FAIL" start="2024-05-09T16:19:17.751806" elapsed="0.026966" />
    </suite>
    <statistics>
        <total>
            <stat pass="0" fail="1" skip="0">All Tests</stat>
        </total>
        <tag></tag>
        <suite>
            <stat pass="0" fail="1" skip="0" id="s1" name="exampleV7">exampleV7</stat>
        </suite>
    </statistics>
    <errors>
</errors>
</robot>

Results in Xray Test Execution Page

Figure 6 - Results

By leveraging these new features in Robot Framework 5.0, 6.0, and 7.0, you can enhance the flexibility, readability, and robustness of your automated Test scripts. Xray's support for these output formats ensures seamless integration and efficient Test management within your projects.

Entities

Each Robot test case is mapped to a Generic Test in Jira, with the summary containing the name of the test case. The Generic Test Definition field includes the concatenated names of the test suites along with the name of the test case. Note that Robot Framework considers the base folder of the project as the first test suite.

The way you run your tests affects Robot's XML. Executing the file from different locations or passing it as an argument directly may result in different test suite information.

The text will be trimmed to match the 255-character limit on the summary field.

Figure 7 - Test details

The name, error message, duration, and status of Robot's keywords will be imported and stored in the Test run results.

The test case keywords and the test case setup/teardown keywords are imported individually, allowing you to see their respective results. However, the test suite setup/teardown keywords are not imported.

Information about each Robot keyword (i.e., step), along with the corresponding status, is displayed in the Context section of the Execution Details of the Generic Test. The example below (Figure 8) shows the execution details page of a test containing both test keywords and the final test teardown keyword.

Figure 8 - Test details

Status

Robot Framework's test case status maps directly to Xray test run statuses: FAIL and PASS.

Message

For passed keywords, the message will be imported from the inner <msg> element within the respective <kw> element (only if the <msg> element has the attribute "level" with values "INFO", "WARN", "ERROR", or "FAIL". "WARN", "ERROR", "FAIL").

For failed keywords, the message will be imported from the inner <msg> element within the respective <kw> element. If the <msg> element does not exist, it will be imported from the text associated with the <status> element defined within the <test> element.

This information will be shown on the Execution screen of the Test run.

Working example

Notes and Limitations

  • Attachments (e.g., screenshots and other files) are not supported or imported as they are not embedded in the XML report. Some libraries add references to their local paths in the <doc/> element, but these cannot be imported as they are external to the report.
  • Nested keywords are not supported.

References