Fixtures are pytest's dependency injection system. Instead of copying setup/teardown code into every test, you declare what a test needs and pytest injects it automatically.
Basic Fixture
import pytest
@pytest.fixture
def sample_user():
return {"name": "Alice", "email": "alice@example.com", "role": "admin"}
def test_user_name(sample_user):
assert sample_user["name"] == "Alice"
def test_user_role(sample_user):
assert sample_user["role"] == "admin"The fixture function name becomes the parameter name in the test — pytest matches them automatically.
Setup and Teardown with yield
import pytest
@pytest.fixture
def db_connection():
conn = create_db_connection() # setup
yield conn # test runs here
conn.close() # teardown (always runs)Code before yield is setup; code after is teardown. The teardown runs even if the test fails.
Fixture Scope
@pytest.fixture(scope="function") # default — new instance per test
@pytest.fixture(scope="class") # one instance per test class
@pytest.fixture(scope="module") # one instance per test file
@pytest.fixture(scope="session") # one instance for the whole test runUse session scope for expensive resources like database connections or browser drivers.
conftest.py
Fixtures in conftest.py are automatically available to all tests in the same directory and below — no import needed.
tests/
├── conftest.py ← fixtures available everywhere
├── test_auth.py
├── api/
│ ├── conftest.py ← fixtures available to api/ tests only
│ └── test_users.py
└── ui/
└── test_homepage.py# tests/conftest.py
import pytest
from myapp import create_app, db
@pytest.fixture(scope="session")
def app():
app = create_app(testing=True)
with app.app_context():
db.create_all()
yield app
db.drop_all()
@pytest.fixture
def client(app):
return app.test_client() # fixtures can use other fixturesFixture Dependency Graph
Fixture dependency chain
Ctrl+Enter
HTML
CSS
JS
Preview
Parametrised Fixtures
@pytest.fixture(params=["sqlite", "postgresql"])
def database(request):
return connect(request.param)
def test_insert(database):
# runs twice — once for sqlite, once for postgresql
assert database.insert({"key": "val"}) == 1pytest creates a separate test case for each param value automatically.