Search code examples
pythonpytestfixtures

Module level fixture is not running


I want to have a specific setup/tear down fixture for one of the test modules. Obviously, I want it to run the setup code once before all the tests in the module, and once after all tests are done.

So, I've came up with this:

import pytest


@pytest.fixture(scope="module")
def setup_and_teardown():
    print("Start")
    yield
    print("End")


def test_checking():
    print("Checking")
    assert True

This does not work that way. It will only work if I provide setup_and_teardown as an argument to the first test in the module.

Is this the way it's supposed to work? Isn't it supposed to be run automatically if I mark it as a module level fixture?


Solution

  • Module-scoped fixtures behave the same as fixtures of any other scope - they are only used if they are explicitely passed in a test, marked using @pytest.mark.usefixtures, or have autouse=True set:

    @pytest.fixture(scope="module", autouse=True)
    def setup_and_teardown():
        print("setup")
        yield
        print("teardown")
    

    For module- and session-scoped fixtures that do the setup/teardown as in your example, this is the most commonly used option.

    For fixtures that yield an object (for example an expansive resource that shall only be allocated once) that is accessed in the test, this does not make sense, because the fixture has to be passed to the test to be accessible. Also, it may not be needed in all tests.