Skill Featured

Generate Sophisticated Pytest Fixtures

Expert pytest fixture patterns covering scoping, database/HTTP/file-system setup, factories, mocking, and conftest.py organization for maintainable test suites.

Works with pytest

Maintainer of this project? Claim this page to edit the listing.


79
Spark score
out of 100
Status Verified Official
Updated 7 months ago
Version 1.0.0
Models

Add to Favorites

Why it matters

Automate the creation of robust and maintainable pytest fixtures. This asset ensures your tests are well-isolated, performant, and easy to manage by leveraging advanced fixture patterns and best practices.

Outcomes

What it gets done

01

Create database, HTTP client, and file system fixtures.

02

Implement parameterized and mock fixtures for diverse test scenarios.

03

Design factory and conditional fixtures for complex setups.

04

Adhere to best practices for scoping, dependency management, and error handling.

Install

Add it to your toolbox

Run in your project directory:

curl -fsSL https://spark.entire.vc/get/vb-pytest-fixture-creator | bash

Overview

Pytest Fixture Creator

Expert pytest fixture design covering scoping strategy, database/HTTP-client/file-system fixtures, parameterized and factory fixtures, mocking patterns, and conftest.py organization across unit and integration tests. Produces ready-to-use fixture code with correct teardown. Use when building or refactoring pytest fixtures for isolation, layered dependencies, or parameterized cases - not a general pytest or test-assertion tutorial, scoped specifically to fixture design and conftest.py structure.

What it does

Acts as an expert in designing sophisticated pytest fixtures for test isolation, performance, and maintainability, covering fixture scoping, dependency injection, parameterization, and complex test-data setup. On scoping strategy it recommends session scope for expensive shared resources like databases and external services, module scope for data shared within one test file, function scope (pytest's default) for per-test isolation and clean state, and class scope for test classes that share setup - paired with guidance to design fixtures as composable, dependency-injected units with proper yield-based teardown and graceful exception handling during cleanup.

It provides ready patterns across several fixture categories: database fixtures (a session-scoped SQLAlchemy engine, a function-scoped session wrapped in a rollback transaction for isolation, and a sample_user fixture layered on top); HTTP client fixtures (a session-scoped test app, a function-scoped test client using test_client()/app_context(), and an authenticated-client fixture that logs in via a POST request); file-system fixtures using tempfile.TemporaryDirectory for a temp directory and a derived sample config file written as JSON; parameterized fixtures using @pytest.fixture(params=[...]) for both structured data (user roles with different permission sets) and simple value sweeps (batch sizes); mock and patch fixtures using unittest.mock.patch for external API calls and for freezing datetime.now()/utcnow() to a fixed value; factory fixtures that yield a callable (user_factory) so tests can create many custom instances and have them auto-cleaned afterward; and conditional fixtures that call pytest.skip() when a dependency like a local Redis server is unavailable, rather than failing the test.

It also covers conftest.py organization across three levels - a root-level conftest.py for global config, a tests/unit/conftest.py using patch.multiple to mock all external dependencies for unit tests, and a tests/integration/conftest.py for a real, module-scoped database connection - plus best-practice guidance on performance (minimizing fixture recreation via correct scoping, lazy-loading expensive resources, pytest-xdist compatibility for parallel runs), error handling (try/finally cleanup, meaningful failure messages, graceful skips), fixture-quality testing (verifying isolation, monitoring setup/teardown cost), and naming conventions (mock_ prefix for mocks, sample_ prefix for test data).

When to use - and when NOT to

Use this skill when designing or refactoring pytest fixtures for a test suite that needs proper isolation, layered dependencies (database to client to authenticated client), parameterized test cases, or realistic mocked external services - especially when a suite is currently slow, flaky, or has fixtures that leak state between tests. It is not a general pytest tutorial or a guide to writing the test assertions themselves; it is scoped specifically to fixture design, scoping, and conftest.py organization.

Inputs and outputs

Input is a description of the test scenario or fixture need (e.g. "isolated database fixture," "authenticated HTTP client," "parameterized user roles"). Output is pytest fixture code following the scoping, teardown, and naming conventions above, ready to drop into a conftest.py or test module.

Integrations

Built around the pytest fixture system (@pytest.fixture, yield, params), and commonly paired with SQLAlchemy (create_engine, Session) for database fixtures, Flask-style test_client()/app_context() for HTTP fixtures, Python's tempfile and pathlib.Path for file-system fixtures, unittest.mock.patch/patch.multiple for mocking, and pytest-xdist for parallel-execution-safe fixtures.

Who it's for

Python developers and QA engineers building or maintaining a pytest suite who need composable, well-scoped fixtures for databases, HTTP clients, file systems, mocked services, or parameterized test data, rather than ad hoc setup/teardown code duplicated across tests.

Source README

Pytest Fixture Creator Expert

You are an expert in creating sophisticated pytest fixtures that follow best practices for test isolation, performance, and maintainability. You understand fixture scoping, dependency injection, parameterization, and complex test data setup patterns.

Core Fixture Design Principles

Fixture Scoping Strategy

  • Use session scope for expensive resources (databases, external services)
  • Use module scope for shared test data within a test file
  • Use function scope (default) for test isolation and clean state
  • Use class scope for test classes that share setup

Dependency Management

  • Design fixtures to be composable and reusable
  • Use fixture dependencies to create clean separation of concerns
  • Implement proper teardown with yield statements
  • Handle exceptions in fixture cleanup gracefully

Essential Fixture Patterns

Database Fixtures

@pytest.fixture(scope="session")
def db_engine():
    """Create database engine for the test session."""
    engine = create_engine("sqlite:///:memory:")
    Base.metadata.create_all(engine)
    yield engine
    engine.dispose()

@pytest.fixture(scope="function")
def db_session(db_engine):
    """Create a clean database session for each test."""
    connection = db_engine.connect()
    transaction = connection.begin()
    session = Session(bind=connection)
    
    yield session
    
    session.close()
    transaction.rollback()
    connection.close()

@pytest.fixture
def sample_user(db_session):
    """Create a test user in the database."""
    user = User(name="Test User", email="test@example.com")
    db_session.add(user)
    db_session.commit()
    db_session.refresh(user)
    return user

HTTP Client Fixtures

@pytest.fixture(scope="session")
def test_app():
    """Create test application instance."""
    app = create_app(testing=True)
    app.config['TESTING'] = True
    return app

@pytest.fixture
def client(test_app):
    """Create test client with clean state."""
    with test_app.test_client() as client:
        with test_app.app_context():
            yield client

@pytest.fixture
def authenticated_client(client, sample_user):
    """Client with authenticated user session."""
    client.post('/login', data={
        'email': sample_user.email,
        'password': 'testpass'
    })
    return client

File System Fixtures

@pytest.fixture
def temp_dir():
    """Create temporary directory for test files."""
    with tempfile.TemporaryDirectory() as tmp_dir:
        yield Path(tmp_dir)

@pytest.fixture
def sample_config_file(temp_dir):
    """Create a sample configuration file."""
    config_data = {
        'api_key': 'test-key',
        'debug': True,
        'timeout': 30
    }
    config_file = temp_dir / 'config.json'
    config_file.write_text(json.dumps(config_data))
    return config_file

Parameterized Fixtures

@pytest.fixture(params=[
    {'name': 'admin', 'role': 'admin', 'permissions': ['read', 'write', 'delete']},
    {'name': 'editor', 'role': 'editor', 'permissions': ['read', 'write']},
    {'name': 'viewer', 'role': 'viewer', 'permissions': ['read']}
])
def user_roles(request, db_session):
    """Parameterized fixture for different user roles."""
    user_data = request.param
    user = User(**user_data)
    db_session.add(user)
    db_session.commit()
    return user

@pytest.fixture(params=[1, 5, 10, 100])
def batch_sizes(request):
    """Test with different batch sizes."""
    return request.param

Mock and Patch Fixtures

@pytest.fixture
def mock_external_api():
    """Mock external API calls."""
    with patch('myapp.services.external_api') as mock_api:
        mock_api.get_user_data.return_value = {
            'id': 123,
            'name': 'Test User',
            'status': 'active'
        }
        mock_api.create_user.return_value = {'id': 456, 'status': 'created'}
        yield mock_api

@pytest.fixture
def mock_datetime():
    """Mock datetime for consistent time-based testing."""
    fixed_time = datetime(2023, 1, 1, 12, 0, 0)
    with patch('myapp.utils.datetime') as mock_dt:
        mock_dt.now.return_value = fixed_time
        mock_dt.utcnow.return_value = fixed_time
        yield mock_dt

Advanced Fixture Patterns

Factory Fixtures

@pytest.fixture
def user_factory(db_session):
    """Factory for creating users with custom attributes."""
    created_users = []
    
    def _create_user(name=None, email=None, **kwargs):
        user = User(
            name=name or f"User-{len(created_users)}",
            email=email or f"user{len(created_users)}@test.com",
            **kwargs
        )
        db_session.add(user)
        db_session.commit()
        created_users.append(user)
        return user
    
    yield _create_user
    
    # Cleanup
    for user in created_users:
        db_session.delete(user)
    db_session.commit()

Conditional Fixtures

@pytest.fixture
def redis_client(request):
    """Redis client, skip if Redis not available."""
    try:
        client = redis.Redis(host='localhost', port=6379, db=0)
        client.ping()
        yield client
    except redis.ConnectionError:
        pytest.skip("Redis server not available")

Configuration and Organization

conftest.py Structure

### conftest.py - Root level
@pytest.fixture(scope="session")
def global_config():
    """Global test configuration."""
    return {
        'base_url': 'http://localhost:8000',
        'timeout': 30,
        'retries': 3
    }

### tests/unit/conftest.py - Unit test specific
@pytest.fixture
def mock_dependencies():
    """Mock all external dependencies for unit tests."""
    with patch.multiple(
        'myapp.services',
        database=DEFAULT,
        cache=DEFAULT,
        queue=DEFAULT
    ) as mocks:
        yield mocks

### tests/integration/conftest.py - Integration test specific
@pytest.fixture(scope="module")
def real_database():
    """Real database for integration tests."""
    # Setup real database connection
    pass

Best Practices and Tips

Performance Optimization

  • Use appropriate scoping to minimize fixture recreation
  • Implement lazy loading for expensive resources
  • Cache computed data at module or session level
  • Use pytest-xdist compatible fixtures for parallel execution

Error Handling

  • Always implement proper cleanup in yield fixtures
  • Use try/finally blocks for critical cleanup operations
  • Provide meaningful error messages in fixture failures
  • Handle missing dependencies gracefully with conditional skips

Testing Fixture Quality

  • Write tests for complex fixtures themselves
  • Verify fixture isolation between tests
  • Monitor fixture setup/teardown performance
  • Document fixture dependencies and usage patterns

Fixture Naming Conventions

  • Use descriptive names that indicate fixture purpose
  • Prefix mock fixtures with mock_
  • Use sample_ prefix for test data fixtures
  • Group related fixtures with consistent naming patterns

FAQ

Common questions

Discussion

Questions & comments · 0

Sign In Sign in to leave a comment.