I found an example how to dynamically create tests. Only problem is, that the teardown is beeing executed 2 times for test that PASS and 1 time for FAILED test. I was playing with _end_test(self, data, result), but didn’t move much. Is there any simple way how to avoid to run the teardown 2 times?
Here is Robot code:
*** Settings ***
Documentation Test cases for dynamic test cases.
# Library files
Library Lib/DynamicTestCases.py
*** Keywords ***
Keyword To Execute
[Arguments] ${variable}
Log The variable sent to the test was: ${variable}
Log To Console This is keyword to execute ${variable}
should be equal ${variable} "Test 1"
Setup keyword
${variable} Set Variable \nThis is from the setup keyword
Log ${variable}
Log To Console ${variable}
Teardown keyword
[TAGS] placeholder
${variable} Set Variable This is from the teardown keyword
Log ${variable}
Log To Console ${variable}
*** Test Cases ***
Create Dynamic Test Cases
@{TestNamesList} Create List "Test 1" "Test 2"
FOR ${element} IN @{TestNamesList}
${testCase} = AddTestCase ${element} dynamic_tag_${element}
AddSetupToTestCase ${testCase} Setup keyword
AddKeywordToTestCase ${testCase} Keyword To Execute ${element}
AddTeardownToTestCase ${testCase} Teardown keyword
END
This is python code:
from robot.running.model import TestCase, Keyword
from robot.api import logger
import sys
class DynamicTestCases:
ROBOT_LISTENER_API_VERSION = 3
ROBOT_LIBRARY_SCOPE = 'TEST SUITE'
def __init__(self):
self.ROBOT_LIBRARY_LISTENER = self
self.currentSuite = None
def _start_suite(self, suite, result):
self.currentSuite = suite
#following didn't work and therefore commented:
#def _end_test(self, data, result):
# if data.has_teardown:
# if result.failed:
# data.teardown = data.teardown
def AddTestCase(self, name, tags):
"""
Adds a test case to the current suite
Args:
- name: is the test case name
- tags: is a list of tags to add to the test case
Returns: The test case that was added
"""
testCase = self.currentSuite.tests.create(name=name, tags=tags)
return testCase
def AddKeywordToTestCase(self, testCase, keywordName, *args):
"""
Adds a keyword to the given test case.
Args:
- testCase: The test case to add the keyword to
- keywordName: The name of the keyword to add
- *args: The arguments to pass to the keyword
"""
testCase.body.create_keyword(name=keywordName, args=args)
def AddSetupToTestCase(self, testCase: TestCase, keywordName: str, *args) -> Keyword:
"""
Adds a setup keyword to the given test case.
Args:
- testCase: The test case to add the keyword to
- keywordName: The name of the keyword to add
- *args: The arguments to pass to the keyword
"""
setupKeyword = testCase.body.create_keyword(name=keywordName, args=args, type='setup')
#Commented as it crete setup 2x
#testCase.setup = setupKeyword
return setupKeyword
def AddTeardownToTestCase(self, testCase: TestCase, keywordName: str, *args) -> Keyword:
"""
Adds a teardown keyword to the given test case.
It is executed twice if the test PASS, and once if test FAIL
Args:
- testCase: The test case to add the keyword to
- keywordName: The name of the keyword to add
- *args: The arguments to pass to the keyword
"""
# following create 1st teardown, that is executed as normal keyword and it's not executed when the test fails
teardownKeyword = testCase.body.create_keyword(name=keywordName, args=args, type='teardown')
#Following ads the teardown that works as teardown - run no matter of test result
testCase.teardown = teardownKeyword
return teardownKeyword