Search code examples
pythontestingautomated-testsrobotframework

Automatic failing/non-execution of interdependent tests in Robot Framework


I have a large number of test cases, in which several test cases are interdependent. Is it possible that while a later test case is getting executed you can find out the status of a previously executed test case? In my case, the 99th test case depends on the status of some prior test cases and thus, if either the 24th or the 38th fails I would like the 99th test case NOT to get executed at all and thus save me a lot of time. Kindly, explain with some example if possible. Thanks in advance!


Solution

  • Robot is very extensible, and a feature that was introduced in version 2.8.5 makes it easy to write a keyword that will fail if another test has failed. This feature is the ability for a library to act as a listener. With this, a library can keep track of the pass/fail status of each test. With that knowledge, you can create a keyword that fails immediately if some other test fails.

    The basic idea is, cache the pass/fail status as each test finishes (via the special _end_test method). Then, use this value to determine whether to fail immediately or not.

    Here's an example of how to use such a keyword:

    *** Settings ***
    Library   /path/to/DependencyLibrary.py
    
    *** Test Cases ***
    Example of a failing test
        fail  this test has failed
    
    Example of a dependent test
        [Setup] | Require test case | Example of a failing test
        log | hello, world
    

    Here is the library definition:

    from robot.libraries.BuiltIn import BuiltIn
    
    class DependencyLibrary(object):
        ROBOT_LISTENER_API_VERSION = 2
        ROBOT_LIBRARY_SCOPE = "GLOBAL"
    
        def __init__(self):
            self.ROBOT_LIBRARY_LISTENER = self
            self.test_status = {}
    
        def require_test_case(self, name):
            key = name.lower()
            if (key not in self.test_status):
                BuiltIn().fail("required test case can't be found: '%s'" % name)
                
            if (self.test_status[key] != "PASS"):
                BuiltIn().fail("required test case failed: '%s'" % name)
    
            return True
    
        def _end_test(self, name, attrs):
            self.test_status[name.lower()] = attrs["status"]