Skip to content
Sarj Code Standards

prefer-pytest-dependency-fixtures

Reuse supplied pytest fixtures and pass test collaborators through fixture dependencies.

Why

Constructing collaborators in a test bypasses pytest's dependency graph, caching and overrides even when only one test currently needs the setup.

Fix

Request function-scoped store, service and settings fixtures by parameter. Use a typed factory fixture for variants or multiple instances. Keep construction under test explicit and preserve setup ordering and the actual owner's cleanup; do not create global singletons or autouse fixtures.

Examples

Before — flagged A test constructs its service's store
tests/test_service.py
from typing import Protocol
class Port(Protocol):
def read(self): ...
class Store:
def read(self):
return 1
class Service:
def __init__(self, store: Port):
self.store = store
def read(self):
return self.store.read()
def test_read():
store = Store()
service = Service(store)
assert service.read() == 1
After — preferred The store arrives through pytest
tests/test_service.py
from typing import Protocol
class Port(Protocol):
def read(self): ...
class Store:
def read(self):
return 1
class Service:
def __init__(self, store: Port):
self.store = store
def read(self):
return self.store.read()
def test_read(store):
service = Service(store)
assert service.read() == 1
Before — flagged A second store bypasses the supplied fixture
tests/test_store.py
from typing import Protocol
class Port(Protocol):
def read(self): ...
class Store:
def read(self):
return 1
class Service:
def __init__(self, store: Port):
self.store = store
def read(self):
return self.store.read()
def test_read(store: Store):
replacement = Store()
assert replacement.read() == 1
After — preferred Use the supplied store fixture
tests/test_store.py
from typing import Protocol
class Port(Protocol):
def read(self): ...
class Store:
def read(self):
return 1
class Service:
def __init__(self, store: Port):
self.store = store
def read(self):
return self.store.read()
def test_read(store: Store):
assert store.read() == 1
Before — flagged A visible plugin fixture owns the collaborator
app/__init__.py
"""Example application package."""
app/stores.py
from abc import ABC, abstractmethod
class Queue(ABC):
@abstractmethod
def retry(self) -> bool: ...
class QueueStore(Queue):
def __init__(self, resource: object) -> None:
self.resource = resource
def retry(self) -> bool:
return True
class Owner:
def __init__(self, resource: object) -> None:
self.resource = resource
def read(self) -> bool:
return True
tests/__init__.py
"""Example test package."""
tests/conftest.py
pytest_plugins = ["tests.fixtures"]
tests/fixtures.py
import pytest
from app.stores import Owner, QueueStore
@pytest.fixture
def resource() -> object:
return object()
@pytest.fixture
def owner(resource: object) -> Owner:
return Owner(resource)
@pytest.fixture
def queue_store(resource: object) -> QueueStore:
return QueueStore(resource)
tests/test_retry.py
from app.stores import Owner, QueueStore
def test_retry(owner: Owner):
queue = QueueStore(owner.resource)
queue.retry()
assert owner.read()
After — preferred Request the collaborator through pytest
app/__init__.py
"""Example application package."""
app/stores.py
from abc import ABC, abstractmethod
class Queue(ABC):
@abstractmethod
def retry(self) -> bool: ...
class QueueStore(Queue):
def __init__(self, resource: object) -> None:
self.resource = resource
def retry(self) -> bool:
return True
class Owner:
def __init__(self, resource: object) -> None:
self.resource = resource
def read(self) -> bool:
return True
tests/__init__.py
"""Example test package."""
tests/conftest.py
pytest_plugins = ["tests.fixtures"]
tests/fixtures.py
import pytest
from app.stores import Owner, QueueStore
@pytest.fixture
def resource() -> object:
return object()
@pytest.fixture
def owner(resource: object) -> Owner:
return Owner(resource)
@pytest.fixture
def queue_store(resource: object) -> QueueStore:
return QueueStore(resource)
tests/test_retry.py
def test_retry(queue_store):
assert queue_store.retry()