Claude Skills Guide

Claude Code Pytest Fixtures Patterns Guide

Pytest fixtures are one of the most powerful features in Python testing, and when combined with Claude Code workflows, they become even more productive. This guide covers practical pytest fixtures patterns that work well with Claude Code sessions, whether you are using the tdd skill for test-driven development or integrating with other automation skills.

Understanding Pytest Fixtures in Claude Code Contexts

When you work with Claude Code using skills like the tdd skill, understanding pytest fixtures helps you communicate more effectively with Claude about test setup and teardown. Fixtures provide a way to set up preconditions for tests, manage resources like database connections or API clients, and share setup code across multiple test functions.

The basic fixture structure uses the @pytest.fixture decorator:

import pytest

@pytest.fixture
def sample_user():
    return {"name": "test_user", "email": "test@example.com", "id": 1}

This fixture can then be injected into any test function that requests it as a parameter:

def test_user_creation(sample_user):
    assert sample_user["name"] == "test_user"
    assert "@" in sample_user["email"]

Fixture Scopes for Different Testing Levels

Pytest provides four fixture scopes: function, class, module, and session. Choosing the right scope reduces redundant setup and improves test execution speed.

The function scope is the default—fixtures run before each test function:

@pytest.fixture
def fresh_database():
    db = Database(":memory:")
    db.initialize()
    yield db
    db.close()

The class scope runs once per test class, useful when multiple tests share expensive setup:

@pytest.fixture(scope="class")
def api_client():
    client = APIClient(base_url="https://api.example.com")
    client.authenticate("test_key")
    yield client

The module scope is ideal for fixtures that should be shared across all tests in a single file:

@pytest.fixture(scope="module")
def test_config():
    return load_config("tests/fixtures/test_config.yaml")

When using these scopes with Claude Code, you can ask the tdd skill to recommend appropriate scopes based on your test dependencies and execution time requirements.

Parametrized Fixtures for Multiple Test Cases

Parametrization allows you to generate multiple test cases from a single fixture or test function. This is particularly useful when testing against multiple inputs or configurations.

@pytest.fixture(params=["development", "staging", "production"])
def environment(request):
    return {
        "name": request.param,
        "base_url": f"https://{request.param}.example.com"
    }

def test_api_endpoints(environment):
    response = requests.get(f"{environment['base_url']}/health")
    assert response.status_code == 200

You can also combine fixtures with parametrization for complex scenarios:

@pytest.fixture(params=[("user", "admin"), ("user", "editor"), ("user", "viewer")])
def user_with_role(request):
    user_type, role = request.param
    return {"type": user_type, "role": role, "permissions": get_permissions(role)}

Autouse Fixtures for Global Setup

The autouse=True parameter runs a fixture automatically for every test without explicit injection. Use this sparingly for global setup like logging configuration or environment variables:

@pytest.fixture(autouse=True)
def setup_test_environment(monkeypatch):
    monkeypatch.setenv("DEBUG", "true")
    monkeypatch.setenv("TESTING", "1")

You can scope autouse fixtures to control when they run:

@pytest.fixture(scope="session", autouse=True)
def session_wide_setup():
    print("Setting up test session")
    yield
    print("Cleaning up test session")

Fixture Teardown with Context Managers

Proper teardown ensures resources are cleaned up regardless of test outcome. Using yield instead of return in fixtures enables teardown code:

@pytest.fixture
def temp_directory(tmp_path):
    test_dir = tmp_path / "test_data"
    test_dir.mkdir()
    yield test_dir
    # Teardown: remove directory after test
    import shutil
    if test_dir.exists():
        shutil.rmtree(test_dir)

For fixtures that need cleanup regardless of whether the test passes or fails, combine try-finally with yield:

@pytest.fixture
def database_connection():
    conn = create_connection()
    try:
        yield conn
    finally:
        conn.close()

Using Fixtures with Claude Skills Integration

When working with Claude Code skills, fixtures become part of your testing vocabulary. The tdd skill understands pytest fixture patterns and can generate appropriate fixtures for your test scenarios.

For example, when using the pdf skill to test PDF generation, you might create fixtures for sample documents:

@pytest.fixture
def sample_pdf_template():
    return {
        "title": "Test Report",
        "sections": ["Introduction", "Methods", "Results", "Conclusion"],
        "author": "Test Author"
    }

def test_pdf_generation(sample_pdf_template):
    pdf = generate_pdf(sample_pdf_template)
    assert pdf.page_count == len(sample_pdf_template["sections"])

The supermemory skill can help you remember complex fixture configurations across projects by storing fixture patterns as searchable knowledge.

Advanced Patterns: Fixture Factories and Dynamic Fixtures

Fixture factories create fixtures that return callable objects for generating test data on demand. For property-based test data generation that pairs well with factories, see the Claude Code hypothesis property testing guide:

@pytest.fixture
def user_factory():
    def _create_user(**overrides):
        defaults = {"name": "default_user", "email": "default@example.com"}
        return {**defaults, **overrides}
    return _create_user

def test_create_custom_user(user_factory):
    user = user_factory(name="custom", email="custom@example.com")
    assert user["name"] == "custom"

Dynamic fixtures based on test parameters allow for flexible test scenarios:

@pytest.fixture
def dynamic_client(request):
    config = request.config
    base_url = config.getoption("--base-url", default="http://localhost:8000")
    return APIClient(base_url=base_url)

Conclusion

Pytest fixtures provide a solid foundation for organizing test setup and teardown in your Claude Code workflows. By mastering fixture scopes, parametrization, autouse patterns, and proper teardown techniques, you create maintainable and efficient test suites. Whether you are working with the tdd skill for test-driven development or combining testing with skills like pdf for document validation, these fixture patterns scale with your project’s complexity.

Built by theluckystrike — More at zovo.one