| name | pytest-fixtures |
| description | Pytest fixture design, conftest.py hierarchy, and DRY test code patterns. Identifies duplicate fixtures, plans fixture scope, and designs conftest.py structure. Use when creating test directories, refactoring test fixtures, or reviewing test code for duplication. |
Pytest Fixtures
Fixture management and conftest.py design for Python test suites.
When to Use
- Creating new test directories
- Refactoring test fixtures
- Reviewing tests for DRY violations
- Planning fixture hierarchy
MCP Workflow
serena.search_for_pattern("conftest\\.py", paths_include_glob="**/tests/**")
serena.search_for_pattern("@pytest\\.fixture", paths_include_glob="**/tests/**")
jetbrains.search_in_files_by_text("def sample_", fileMask="test_*.py")
serena.get_symbols_overview(relative_path="tests/")
Fixture Hierarchy
tests/
├── conftest.py # Shared across ALL tests
│ └── Fixtures: session-scoped, DB connections, API clients
├── cli/
│ ├── conftest.py # CLI-specific fixtures
│ │ └── Fixtures: CLI runner, mock console, sample paths
│ └── test_*.py
└── core/
├── conftest.py # Core-specific fixtures
│ └── Fixtures: domain models, sample data
└── {module}/
├── conftest.py # Module-specific (rarely needed)
└── test_*.py
Scope Selection Guide
| Scope | Recreated | Use When |
|---|
function | Each test | Default; mutable state |
class | Each class | Class-based tests, shared setup |
module | Each file | Expensive setup, immutable data |
session | Once | DB connections, API clients |
Rule: Start with function, widen scope only for performance.
Fixture Design Patterns
1. Factory Fixture (Preferred for Flexibility)
@pytest.fixture
def make_user():
"""Factory that creates users with custom attributes."""
def _make_user(name: str = "test", role: str = "user") -> User:
return User(name=name, role=role)
return _make_user
def test_admin_access(make_user):
admin = make_user(role="admin")
assert admin.can_access_admin_panel()
2. Parameterized Fixture
@pytest.fixture(params=["sqlite", "postgres", "mysql"])
def database(request):
"""Runs test with each database type."""
return create_connection(request.param)
3. Cleanup Fixture (yield pattern)
@pytest.fixture
def temp_file(tmp_path):
"""Provides temp file and cleans up after test."""
path = tmp_path / "test.txt"
path.write_text("content")
yield path
Duplicate Detection Checklist
Run before creating fixtures:
grep -r "@pytest.fixture" tests/ | grep "def " | cut -d: -f2 | sort | uniq -d
grep -rh "def get_output\|def create_\|def make_\|def sample_" tests/
conftest.py Planning
Before Creating New Test Directory
- Check parent conftest - What fixtures already exist?
- Identify shared fixtures - What 2+ tests need?
- Plan fixture scope - Function/module/session?
- Document dependencies - What does each fixture need?
conftest.py Template
"""
Fixtures for {directory} tests.
Shared fixtures:
- {fixture_name}: {description}
Dependencies:
- Uses: {parent_fixture} from parent conftest
"""
import pytest
@pytest.fixture
def fixture_name():
"""One-line description."""
return value
DRY Violation Patterns
| Pattern | Problem | Solution |
|---|
| Same fixture in 2+ files | Maintenance burden | Move to shared conftest |
get_output() in multiple files | Helper duplication | Create helpers.py |
| Copy-paste setup code | Test fragility | Factory fixture |
| Inline data creation | Readability | Data fixtures |
Helper Function Consolidation
tests/
├── conftest.py # Fixtures only
├── helpers.py # Shared utility functions
│ ├── get_output()
│ ├── assert_table_contains()
│ └── create_mock_response()
└── fixtures/ # Complex fixture data
├── sample_metrics.json
└── sample_datasets.yaml
Output Format
## Fixture Analysis: {directory}
### Existing Fixtures
| Location | Fixture | Scope | Used By |
|----------|---------|-------|---------|
| tests/conftest.py | db_session | session | 15 tests |
| tests/cli/conftest.py | cli_runner | function | 8 tests |
### Issues Found
1. **Duplicate**: `sample_project_path` in test_a.py and test_b.py
- Action: Move to tests/cli/conftest.py
2. **Missing conftest**: tests/core/workflow/ has no conftest
- Action: Create with shared fixtures
### Recommendations
- [ ] Create tests/cli/conftest.py with: cli_runner, mock_console
- [ ] Move get_output() to tests/helpers.py
- [ ] Change db_session scope from function to module
Quality Checklist