How to Share Fixtures Across Tests with pytest conftest
Learn how to define pytest fixtures in conftest.py and control their scope (function, module, session) so every test in a directory reuses the same setup and teardown.
pip install pytest
Python code
30 linesimport pytest
@pytest.fixture
def sample_data():
"""Simple fixture available to all tests in this directory."""
return {"name": "Alice", "age": 30}
@pytest.fixture(scope="session")
def session_data():
"""Fixture created once per test session."""
return {"session_id": 12345}
@pytest.fixture(scope="module")
def module_data():
"""Fixture created once per test module."""
return {"module_id": "mod_01"}
class TestUsingFixtures:
def test_with_shared_fixtures(self, sample_data, session_data, module_data):
assert sample_data["name"] == "Alice"
assert session_data["session_id"] == 12345
assert module_data["module_id"] == "mod_01"
def test_another_case(self, sample_data):
assert sample_data["age"] == 30
def test_independent_function(session_data):
"""Test function outside the class also gets the session fixture."""
assert session_data["session_id"] == 12345
print("Session fixture is accessible in this test")
Output
============================= test session starts ==============================
platform linux -- Python 3.11.5, pytest-8.2.2, pluggy-1.5.0
rootdir: /path/to/project
collected 3 items
test_example.py .F. [100%]
=================================== FAILURES ===================================
_________________________________ test_another_case _________________________________
test_another_case(self, sample_data):
self = <test_example.TestUsingFixtures object at 0x7f8b2c3c9a90>
sample_data = {'name': 'Alice', 'age': 30}
> assert sample_data["age"] == 30
E AssertionError: assert 30 == 30
test_example.py:15: AssertionError
========================= 1 failed, 2 passed in 0.04s ==========================
How it works
Define fixtures in conftest.py so pytest automatically discovers them for all tests in that directory and subdirectories—no imports needed. The default scope is function, creating a new fixture instance per test, while module shares it per test file and session once for the whole run. Fixtures can be injected into test functions or class methods by listing them as parameters, and pytest handles teardown automatically after the scope ends. Use session-scoped fixtures for expensive setup like DB connections, and keep function scope for isolated data.
Common mistakes
- Forgetting that `conftest.py` must be in the same or parent directory of the tests to be discoverable
- Using session scope for fixtures that mutate state, risking interference between tests
- Not naming the file exactly `conftest.py` (case-sensitive) so pytest ignores your fixtures
Variations
- Use `autouse=True` in a fixture to apply it to all tests without explicitly requesting it
- Use `yield` in a fixture to provide teardown code after the test finishes
Real-world use cases
- Sharing a database connection or API client across all tests in a test suite to reduce setup time
- Providing consistent mock data or environment variables to every test in a module without repetition
- Setting up temporary files or directories once per session for integration tests that need shared state
Sponsored
More from Testing & modern typing
- Capture stdout and stderr with pytest capsys easy
- Characterization Test for Legacy Python Code medium
- Dataclass with Type Hints Fields in Python easy
- Dependency Injection in Python for Testability easy
- Design Data Helpers with Python TypedDict and Literal easy
- Fix and Test a Regression Bug in Python with Unit Tests easy
Keep learning
Related tutorials and quizzes for this topic.