Question

I have different test folders(packages). I want to setup and teardown some data for a specific package(folder).

The problem is set_up() is executed before running the test cases of that folder but after running all the testcases, tear_down is not executing. It's executing after running all the testcases of other packages (folders) also(after whole session of pytest).

     [conftest.py]

     @pytest.fixture(scope="session", autouse=True)
         def set_up(request):
            '''Test package setup'''

         def tear_down():
            '''Test package teardown'''

Each folder contains __init__.py file which is obvious.

So how do i execute the tear_down() just after running all the testcases in that folder for which set_up is executed?

as far i know: scope="module" is useless in this case as i dont want to setup and teardown for each test.

Any help would be great. Thanks

Was it helpful?

Solution

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.

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top