Agent skill
setup-pytest-fixtures
Creates pytest fixtures following project patterns including factory fixtures, async fixtures, and multi-layer organization. Use when setting up test fixtures, creating test data, organizing test utilities, or structuring conftest.py files. Works with Python test files, pytest configuration, and .py test utilities.
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/data/setup-pytest-fixtures
SKILL.md
Setup Pytest Fixtures
Purpose
Creates pytest fixtures following project-watch-mcp patterns: factory fixtures for customization, async fixtures for async code, centralized organization in tests/utils/, and proper conftest.py hierarchy.
Quick Start
Create a basic fixture:
import pytest
@pytest.fixture
def mock_settings():
"""Create mock settings for testing."""
settings = MagicMock()
settings.project = MagicMock()
settings.project.project_name = "test_project"
return settings
Create a factory fixture:
@pytest.fixture
def mock_settings_factory():
"""Factory for custom mock settings."""
def create_settings(**kwargs):
settings = MagicMock()
settings.project = MagicMock()
settings.project.project_name = kwargs.get("project_name", "test_project")
return settings
return create_settings
Instructions
Step 1: Identify Fixture Type
Determine which fixture pattern to use:
-
Basic Fixture: Simple, reusable test data
- Use for: Constant values, simple mocks
- Example:
mock_settings_minimal
-
Factory Fixture: Customizable with parameters
- Use for: Configurable test data, parameterized tests
- Example:
mock_settings_factory(**kwargs)
-
Async Fixture: For async operations
- Use for: Async setup/teardown, async resources
- Example:
@pytest_asyncio.fixture async def...
-
Scoped Fixture: Shared across multiple tests
- Use for: Expensive setup, session-wide resources
- Example:
@pytest.fixture(scope="session")
Step 2: Choose Organization Strategy
Centralized Utilities (Recommended for reusable fixtures):
- Location:
tests/utils/ - Files:
mock_settings.py,mock_services.py,mock_drivers.py,environmental_helpers.py - Import in:
tests/conftest.pyto make available project-wide
Local Conftest (For layer-specific fixtures):
- Location:
tests/unit/conftest.py,tests/integration/conftest.py,tests/e2e/conftest.py - Use for: Fixtures specific to that test layer
Test File (For test-specific fixtures):
- Location: Same file as tests
- Use for: One-off fixtures not reused elsewhere
Step 3: Implement Fixture
For Basic Fixtures:
import pytest
from unittest.mock import MagicMock
@pytest.fixture
def fixture_name():
"""Clear docstring explaining purpose."""
# Setup
obj = MagicMock()
obj.attribute = "value"
# Return (no yield for simple fixtures)
return obj
For Factory Fixtures:
@pytest.fixture
def fixture_factory():
"""Factory for custom fixture."""
def create_fixture(**kwargs):
"""Create fixture with custom attributes.
Args:
**kwargs: Attributes to customize
Returns:
MagicMock: Configured fixture
"""
obj = MagicMock()
obj.attribute = kwargs.get("attribute", "default_value")
return obj
return create_fixture
For Async Fixtures:
import pytest_asyncio
from collections.abc import AsyncGenerator
@pytest_asyncio.fixture(scope="function")
async def async_fixture() -> AsyncGenerator[Resource, None]:
"""Async fixture with setup and teardown."""
# Setup
resource = await create_resource()
yield resource
# Teardown
await resource.close()
For Scoped Fixtures:
@pytest.fixture(scope="session")
def session_fixture():
"""Session-scoped fixture created once."""
# Expensive setup
resource = expensive_setup()
yield resource
# Cleanup after all tests
resource.cleanup()
Step 4: Add to Conftest Hierarchy
In tests/utils/mock_*.py:
"""Reusable mock fixtures for [component] components."""
from unittest.mock import MagicMock
import pytest
@pytest.fixture
def fixture_name():
"""Fixture docstring."""
return MagicMock()
In tests/conftest.py:
# Import to make available project-wide
from tests.utils.mock_settings import (
fixture_name,
)
__all__ = [
"fixture_name",
]
In layer-specific conftest:
# tests/unit/conftest.py
import pytest
@pytest.fixture
def unit_specific_fixture():
"""Fixture only for unit tests."""
return MagicMock()
Step 5: Use Fixtures in Tests
Basic usage:
def test_something(fixture_name):
"""Test using fixture."""
assert fixture_name.attribute == "value"
Factory usage:
def test_with_factory(fixture_factory):
"""Test using factory fixture."""
custom = fixture_factory(attribute="custom_value")
assert custom.attribute == "custom_value"
Async usage:
@pytest.mark.asyncio
async def test_async(async_fixture):
"""Test using async fixture."""
result = await async_fixture.operation()
assert result == expected
Multiple fixtures:
def test_with_multiple(fixture_one, fixture_two, fixture_factory):
"""Test using multiple fixtures."""
custom = fixture_factory(value="test")
assert fixture_one.works_with(fixture_two, custom)
Examples
Example 1: Basic Mock Fixture
import pytest
from unittest.mock import MagicMock
@pytest.fixture
def mock_settings_minimal():
"""Create minimal mock settings for basic testing."""
settings = MagicMock()
settings.project = MagicMock()
settings.project.project_name = "test_project"
settings.neo4j = MagicMock()
settings.neo4j.database_name = "test_db"
return settings
Example 2: Factory Fixture
@pytest.fixture
def mock_settings_factory():
"""Factory for custom mock settings."""
def create_settings(**kwargs):
settings = MagicMock()
settings.project = MagicMock()
settings.project.project_name = kwargs.get("project_name", "test_project")
settings.neo4j = MagicMock()
settings.neo4j.database_name = kwargs.get("database_name", "test_db")
settings.chunking = MagicMock()
settings.chunking.chunk_size = kwargs.get("chunk_size", 50)
return settings
return create_settings
Example 3: Async Fixture with Cleanup
import pytest_asyncio
from collections.abc import AsyncGenerator
from neo4j import AsyncGraphDatabase, AsyncDriver
@pytest_asyncio.fixture(scope="function")
async def real_neo4j_driver() -> AsyncGenerator[AsyncDriver, None]:
"""Create a real Neo4j driver with cleanup."""
driver = AsyncGraphDatabase.driver(
"bolt://localhost:7687",
auth=("neo4j", "password")
)
# Setup: Clear test data
async with driver.session(database="test_db") as session:
await session.run("MATCH (n {project_name: 'test_project'}) DETACH DELETE n")
yield driver
# Teardown: Close driver
await driver.close()
Script Files:
- scripts/generate_fixture.py - Auto-generate pytest fixtures following project patterns
- scripts/analyze_fixture_usage.py - Analyze pytest fixture usage and find optimization opportunities
- scripts/organize_fixtures.py - Reorganize fixtures by layer and update imports
Requirements
- pytest installed:
uv pip install pytest - pytest-asyncio for async fixtures:
uv pip install pytest-asyncio - Understanding of project structure:
tests/utils/- Centralized reusable fixturestests/conftest.py- Project-wide fixture importstests/unit/conftest.py- Unit test specific fixturestests/integration/conftest.py- Integration test specific fixturestests/e2e/conftest.py- E2E test specific fixtures
Fixture Best Practices
- Naming: Use descriptive names with
mock_prefix for mocks - Docstrings: Always document what the fixture provides
- Scope: Default to
functionscope, usesession/moduleonly when needed - Cleanup: Use
yieldfor fixtures that need teardown - Factory Pattern: Return callable for customizable fixtures
- Type Hints: Add return type hints for better IDE support
- Reusability: Place reusable fixtures in
tests/utils/, import inconftest.py - Layer Isolation: Keep layer-specific fixtures in layer conftest files
Common Patterns
Settings Mock:
@pytest.fixture
def mock_settings():
"""Standard settings mock."""
settings = MagicMock()
settings.project = MagicMock()
settings.neo4j = MagicMock()
return settings
Service Result Mock:
@pytest.fixture
def mock_service_result():
"""Factory for ServiceResult mocks."""
def create_result(success=True, data=None, error=None):
result = MagicMock()
result.is_success = success
result.data = data
result.error = error
return result
return create_result
Async Service Mock:
@pytest.fixture
def mock_embedding_service():
"""Async embedding service mock."""
service = AsyncMock()
service.generate_embeddings = AsyncMock(
return_value=MagicMock(success=True, data=[[0.1] * 384])
)
return service
Troubleshooting
Fixture not found:
- Check it's imported in
tests/conftest.py - Verify file is in Python path
- Ensure
__all__includes fixture name
Async fixture errors:
- Install
pytest-asyncio:uv pip install pytest-asyncio - Use
@pytest_asyncio.fixturenot@pytest.fixture - Mark test with
@pytest.mark.asyncio
Scope issues:
- Session fixtures can't use function fixtures
- Use broader scope for dependent fixtures
- Consider fixture dependencies carefully
Cleanup not running:
- Use
yieldnotreturn - Ensure async cleanup uses
await - Check for exceptions during test
Automation Scripts
NEW: Powerful automation utilities for fixture management:
scripts/generate_fixture.py
Auto-generate fixtures with proper patterns:
python .claude/skills/setup-pytest-fixtures/scripts/generate_fixture.py \
--name mock_service --type factory --attributes host,port,timeout
scripts/analyze_fixture_usage.py
Analyze fixture usage and find optimization opportunities:
python .claude/skills/setup-pytest-fixtures/scripts/analyze_fixture_usage.py --unused
scripts/organize_fixtures.py
Reorganize fixtures by layer and update imports:
python .claude/skills/setup-pytest-fixtures/scripts/organize_fixtures.py --validate
See Also
- templates/fixture-templates.md - Copy-paste templates
tests/utils/mock_settings.py- Settings fixture referencetests/utils/mock_services.py- Service fixture referencetests/utils/mock_drivers.py- Driver fixture referencetests/utils/environmental_helpers.py- Environment fixture reference
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
Didn't find tool you were looking for?