Fixtures
Fixtures provide test dependencies - database connections, API clients, sample data - via dependency injection. Define once in conftest.py, inject by parameter name.
Search across all documentation pages
Fixtures provide test dependencies - database connections, API clients, sample data - via dependency injection. Define once in conftest.py, inject by parameter name.
# tests/conftest.py
import pytest
@pytest.fixture
def sample_user():
return {"id": 1, "email": "ada@example.com"}
# tests/test_users.py
def test_user_email(sample_user):
assert "@" in sample_user["email"]When to reach for this:
# tests/conftest.py
import pytest
from sqlalchemy import create_engine
from sqlalchemy.orm import Session
@pytest.fixture(scope="session")
def engine():
eng = create_engine("sqlite:///:memory:")
yield eng
eng.dispose()
@pytest.fixture
def db_session(engine):
connection = engine.connect()
transaction = connection.begin()
session = Session(bind=connection)
yield session
session.close()
transaction.rollback()
connection.close()
@pytest.fixture
def user_factory(db_session):
def _make(email: str = "test@example.com"):
user = User(email=email)
db_session.add(user)
db_session.flush()
return user
return _makedef test_create_user(user_factory):
user = user_factory(email="ada@example.com")
assert user.id is not NoneWhat this demonstrates:
scope="session" shares the engine across all testsdb_session rolls back for isolationyield fixtures run teardown after the test| Scope | Lifetime | Use for |
|---|---|---|
| function | One test | Default, most fixtures |
| class | One test class | Shared class setup |
| module | One file | Expensive per-file setup |
| session | Entire run | DB engine, app instance |
@pytest.fixture
def api_client(app):
return TestClient(app)api_client automatically receives the app fixture.
yield fixtures for cleanup.| Alternative | Use When | Don't Use When |
|---|---|---|
| setUp/tearDown | unittest style | pytest project |
| Manual setup in each test | One-off cases | Shared setup |
| Factory pattern (no fixture) | Simple data | Need teardown |
conftest.py in tests/ or subdirectories. Auto-discovered by pytest.
yield enables teardown code after the test. return has no teardown.
Declare it as a parameter: def api(app): ....
@pytest.fixture(autouse=True) runs for every test in scope without being requested.
Redefine it in a subdirectory conftest.py or use @pytest.fixture(name="...").
Yes with pytest-asyncio: @pytest.fixture + async def.
@pytest.fixture(params=[1, 2, 3]) runs the test once per param value.
request.getfixturevalue("name") inside a fixture or test.
Session fixtures persist state. Ensure tests do not mutate shared objects.
Fixture provides an instance. Factory fixture returns a function that creates instances.
Stack versions: This page was written for Python 3.14.0, FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, and uv 0.6+.
Reviewed by Chris St. John·Last updated Jul 19, 2026