How to call setup once for all tests and teardown after all are finished

25,093

Solution 1

The OP's requirement was for setup and teardown each to execute only once, not one time per module. This can be accomplished with a combination of a conftest.py file, @pytest.fixture(scope="session") and passing the fixture name to each test function.

These are described in the Pytest fixtures documentation

Here's an example:

conftest.py

import pytest

@pytest.fixture(scope="session")
    def my_setup(request):
        print '\nDoing setup'
        def fin():
            print ("\nDoing teardown")
        request.addfinalizer(fin)

test_something.py

def test_dummy(my_setup):
    print '\ntest_dummy'

test_something2.py

def test_dummy2(my_setup):
    print '\ntest_dummy2'

def test_dummy3(my_setup):
    print '\ntest_dummy3'

The output when you run py.test -s:

collected 3 items 

test_something.py 
Doing setup

test_dummy
.
test_something2.py 
test_dummy2
.
test_dummy3
.
Doing teardown

The name conftest.py matters: you can't give this file a different name and expect Pytest to find it as a source of fixtures.

Setting scope="session" is important. Otherwise setup and teardown will be repeated for each test module.

If you'd prefer not to pass the fixture name my_setup as an argument to each test function, you can place test functions inside a class and apply the pytest.mark.usefixtures decorator to the class.

Solution 2

Put setup_module and teardown_module outside of a class on module level. Then add your class with your tests.

def setup_module(module):
    """..."""

def teardown_module(module):
    """..."""

class TestSomething:

    def test_dummy(self):
        """do some tests"""

For more info refer to this article.

Solution 3

setup_module/teardown_module are called for the module where the eventual (derived) tests are defined. This also allows to customize the setup. If you only ever have one setup_module you can put it to test_base.py and import it from the other places. HTH.

Share:
25,093

Related videos on Youtube

vinodkone
Author by

vinodkone

Updated on September 05, 2020

Comments

  • vinodkone
    vinodkone over 3 years

    I have a bunch of tests written using pytest. There are all under a directory dir. For example:

    dir/test_base.py
    dir/test_something.py
    dir/test_something2.py
    ...
    

    The simplified version of code in them is as follows:

    test_base.py

    import pytest
    
    class TestBase:
       def setup_module(module):
          assert False
    
       def teardown_module(module):
          assert False
    

    test_something.py

    import pytest
    from test_base import TestBase
    
    class TestSomething(TestBase):
       def test_dummy():
           pass
    

    test_something2.py

    import pytest
    from test_base import TestBase
    
    class TestSomethingElse(TestBase):
       def test_dummy2():
           pass
    

    All my test_something*.py files extend the base class in test_base.py. Now I wrote setup_module(module) and teardown_module(module) methods in test_base.py. I was expecting the setup_module to be called once for all tests, and teardown_module() to be called at the end, once all tests are finished.

    But the functions don’t seem to be getting called? Do I need some decorators for this to work?

  • jdi
    jdi over 12 years
    Is there a reason this answer doesn't address specifically his trouble using the document-defined Module level setup/teardown. Are you suggesting the setup_module(module) / teardown_module(module) functions do not work as documented?
  • jdi
    jdi over 12 years
    Im just asking if you are implying that those documented methods do not work, as suggested by your answer to do it in the init instead. Thats all. Because even in your link, you reference to the doc that explains to use those methods, which are broken for the OP
  • vinodkone
    vinodkone over 12 years
    Hi @GiacomoSpettoli thanks for your reply. I am actually looking for getting setup_module/teardown_module to work, instead of setup_class/teardown_class. Because, I want these to be invoked only once for all tests. setup_class/teardown_class will be called for each of my tests that derive my base class. HTH
  • vinodkone
    vinodkone over 12 years
    i edited my qsn about to show my code. Is this what you mean? because, that doesn't work...
  • Giacomo Spettoli
    Giacomo Spettoli over 12 years
    I see...so you should try to put those methods in the __ init __.py. That was my first answer but I changed it because, without your last constraint, the use of class methods looked cleaner.
  • hpk42
    hpk42 over 12 years
    setup_module needs to be defined at module level, not class level.
  • vinodkone
    vinodkone over 12 years
    hi @hpk42 what does that mean exactly? sorry, i'm a python noob.
  • hpk42
    hpk42 over 12 years
    "module-level" means at indentation level 0 in your file (same level where you define the class). You currently define setup_module within the class definition.
  • jxramos
    jxramos almost 4 years
    are those permitted in conftest.py files?
  • Justin Hammond
    Justin Hammond about 2 years
    @jxramos based on my testing, they are not. You could place them in your init.py file in your test suite directory though.