Search code examples
pythonpytestfixtures

How are pytest fixure scopes intended to work?


I want to use pytest fixtures to prepare an object I want to use across a set of tests. I follow the documentation and create a fixture in something_fixture.py with its scope set to session like this:

import pytest

@pytest.fixture(scope="session")
def something():
    return 'something'

Then in test_something.py I try to use the fixture like this:

def test_something(something):
    assert something == 'something'

Which does not work, but if I import the fixture like this:

from tests.something_fixture import something


def test_something(something):
    assert something == 'something'

the test passes...

Is this import necessary? Because to me this is not clear according to the documentation.


Solution

  • This session-scoped fixture should be defined in a conftest.py module, see conftest.py: sharing fixtures across multiple files in the docs.

    The conftest.py file serves as a means of providing fixtures for an entire directory. Fixtures defined in a conftest.py can be used by any test in that package without needing to import them (pytest will automatically discover them).

    By writing the fixture in something_fixture.py it was defined somewhere that went "unnoticed" because there was no reason for Python to import this module. The default test collection phase considers filenames matching these glob patterns:

    - test_*.py
    - *_test.py
    

    Since it's a session-scoped feature, define it instead in a conftest.py file, so it will be created at test collection time and available to all tests.

    You can remove the import statement from tests.something_fixture import something. In fact the "tests" subdirectory generally doesn't need to be importable at all.