setup/teardown using conftest in pytest

conftest.py files are directory-level (read "package") configurations. So if you put one at the root directory of your tests, its session-scoped fixtures will run at the beginning of that scope and the corresponding tear_down will wait for the scope's conclusion (i.e. the entire test session) before executing. If you need to create fixtures that span only sub-directories (sub-packages), you need to put additional conftest.py files at those levels (with their own scope='session' fixtures). A common example is to add data to a database. Imagine wanting to populate your purchases db table with some rows for all your tests inside the corresponding test package. You'd place the fixture that does the job inside tests.purchases.conftest.py.

shopping_app/
tests/
    __init__.py
    conftest.py # applies to all tests
    buyers/
    products/
    purchases/
        conftest.py # only applies to this scope and sub-scopes
        __init__.py
        test1.py
        test2.py
        payments/
        refunds/
    sellers/
    stores/

And inside tests.purchases.conftest.py you'd have ordinary fixture declarations. For instance a set_up/tear_down combo to prepopulate and delete rows for your db table would looks something like this:

@pytest.fixture(scope='session', autouse=True)
def prep_purchases(db, data):
    # set_up: fill table at beginning of scope
    populate_purchase_table_with_data(db, data)

    # yield, to let all tests within the scope run
    yield 

    # tear_down: then clear table at the end of the scope
    empty_purchase_table(db)

Some fixtures do not need to be explicitly injected into tests (we're only interested by their side-effect, not their return value), hence the autouse parameter. As for the context manager syntax for set_up/tear_down (with yield), if you're not comfortable with it, you can alternatively place the tear_down part as its own separate function.


pytest does not directly support package level fixtures. Neither does unittest.

As for the main test frameworks, I believe nose is the only one to support package fixtures. However, nose2 is dropping package fixture support. See nose2 docs.

pytest supports module, function, class, and method level fixtures for xunit style fixtures.