# Duplicite teardown (and setup) with Dynamic test cases

**URL:** <https://forum.robotframework.org/t/duplicite-teardown-and-setup-with-dynamic-test-cases/6661>\
**Category:** Robot Framework\
**Created:** [15 January 2024 12:23 UTC](https://forum.robotframework.org/t/duplicite-teardown-and-setup-with-dynamic-test-cases/6661 "2024-01-15T12:23:13Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![MartinS-1](https://dub1.discourse-cdn.com/flex005/user_avatar/forum.robotframework.org/martins-1/32/3344_2.png) [@MartinS-1](https://forum.robotframework.org/u/MartinS-1)\
**Post date:** [15 January 2024 12:23 UTC](https://forum.robotframework.org/t/duplicite-teardown-and-setup-with-dynamic-test-cases/6661/1 "2024-01-15T12:23:13Z")

</div>

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

```

---

<div class="post-metadata">

**Author:** ![MartinS-1](https://dub1.discourse-cdn.com/flex005/user_avatar/forum.robotframework.org/martins-1/32/3344_2.png) [@MartinS-1](https://forum.robotframework.org/u/MartinS-1)\
**Post date:** [16 January 2024 08:18 UTC](https://forum.robotframework.org/t/duplicite-teardown-and-setup-with-dynamic-test-cases/6661/2 "2024-01-16T08:18:27Z")

</div>

I found the answer:

```
    teardownKeyword = testCase.body.create_keyword(name=keywordName, args=args, type='teardown')
    # remove duplicite teardown
    testCase.body.remove(teardownKeyword) 
    testCase.teardown = teardownKeyword
    return teardownKeyword

```

---

<div class="post-metadata">

**Author:** ![MartinS-1](https://dub1.discourse-cdn.com/flex005/user_avatar/forum.robotframework.org/martins-1/32/3344_2.png) [@MartinS-1](https://forum.robotframework.org/u/MartinS-1)\
**Post date:** [24 January 2024 08:54 UTC](https://forum.robotframework.org/t/duplicite-teardown-and-setup-with-dynamic-test-cases/6661/3 "2024-01-24T08:54:22Z")

</div>

Better idea:

```
testCase.teardown = Keyword(name=keywordName, args=args, type='teardown')

```
