Skill

python3-test-design

Use when designing pytest test suite architecture, planning test coverage strategy, or reviewing test structure for Python 3.11+ projects. Activates on "design a test strategy", "plan test coverage", "create test architecture", or when TDD/BDD/property-based testing patterns are mentioned. Guides fixture design, parametrization, async testing, and mutation testing coverage decisions.

From python3-development
Install
1
Run in your terminal
$
npx claudepluginhub jamie-bitflight/claude_skills --plugin python3-development
Tool Access

This skill uses the workspace's default tool permissions.

Skill Content

Python Test Design Skill

Guidance for designing pytest test suites with modern Python 3.11+ patterns.

When to Use This Skill

Use this skill for test design decisions:

  • Planning test suite architecture
  • Choosing testing strategies (unit, integration, e2e)
  • Designing fixture hierarchies
  • Determining coverage strategies
  • Planning property-based testing approach

For test implementation, use the python-pytest-architect agent instead.

Test Design Principles

Consult ../python3-development/references/python3-standards.md when aligning test strategy with shared plugin testing norms. The strategies below supplement that document; they do not replace it.

Test Pyramid

Structure test suites following the test pyramid:

        /\
       /  \     E2E (few, slow, high confidence)
      /----\
     /      \   Integration (moderate, medium speed)
    /--------\
   /          \ Unit (many, fast, focused)
  /------------\

Distribution targets:

  • Unit tests: 70-80% of test count
  • Integration tests: 15-25% of test count
  • E2E tests: 5-10% of test count

Test Naming Convention

Use behavioral naming that describes what is being tested:

# Pattern: test_{function}_{scenario}_{expected_result}

def test_validate_email_with_invalid_format_raises_validation_error():
    """Validate that malformed emails are rejected."""
    ...

def test_process_payment_when_insufficient_funds_returns_declined():
    """Payment processing declines when balance is insufficient."""
    ...

AAA Pattern (Arrange-Act-Assert)

Structure every test with clear sections:

def test_user_registration_creates_account():
    # Arrange
    user_data = {"email": "test@example.com", "name": "Test User"}
    repository = InMemoryUserRepository()
    service = UserService(repository)

    # Act
    result = service.register(user_data)

    # Assert
    assert result.success is True
    assert repository.count() == 1

Test Strategy Selection

When to Use Unit Tests

  • Pure functions with no side effects
  • Business logic validation
  • Data transformation
  • Algorithm correctness

When to Use Integration Tests

  • Database interactions
  • External API calls
  • File system operations
  • Multi-component workflows

When to Use Property-Based Tests

  • Functions with mathematical properties (commutativity, associativity)
  • Parsers and serializers (round-trip property)
  • Data validation (valid inputs always accepted)
  • State machines (invariants maintained)
from hypothesis import given, strategies as st

@given(st.lists(st.integers()))
def test_sort_maintains_length(data):
    """Sorting preserves all elements."""
    result = sorted(data)
    assert len(result) == len(data)

When to Use BDD Tests

  • User-facing features with acceptance criteria
  • Requirements traceability needed
  • Non-technical stakeholder visibility
  • Complex user workflows

Fixture Design

Fixture Hierarchy

Organize fixtures by scope and purpose:

conftest.py (root)
├── Session fixtures (db connections, servers)
├── Module fixtures (shared test data)
└── Function fixtures (isolated per-test data)

tests/
├── conftest.py              # Shared fixtures
├── unit/
│   └── conftest.py          # Unit-specific fixtures
└── integration/
    └── conftest.py          # Integration-specific fixtures

Factory Pattern for Test Data

Use factories for complex test objects:

import factory
from datetime import datetime, UTC

class UserFactory(factory.Factory):
    class Meta:
        model = User

    id = factory.Sequence(lambda n: n)
    email = factory.LazyAttribute(lambda o: f"user{o.id}@example.com")
    created_at = factory.LazyFunction(lambda: datetime.now(UTC))

Coverage Strategy

Minimum Coverage Requirements

Code TypeMinimum Coverage
Business logic90%
Standard code80%
Scripts/utilities70%
Critical paths95% + mutation testing

Coverage Configuration

# pyproject.toml
[tool.coverage.run]
branch = true
source = ["packages"]
omit = ["**/tests/**", "**/__pycache__/**"]

[tool.coverage.report]
fail_under = 80
exclude_lines = [
    "pragma: no cover",
    "if TYPE_CHECKING:",
    "raise NotImplementedError",
]

Mutation Testing for Critical Code

Apply mutation testing to security-critical and payment-related code:

# Run mutation tests on auth module
uv run mutmut run --paths-to-mutate=packages/auth/

# View surviving mutants
uv run mutmut results

Target: >90% mutation score for critical code paths

Test Directory Structure

tests/
├── conftest.py              # Shared fixtures, pytest plugins
├── unit/                    # Fast, isolated tests
│   ├── test_validators.py
│   └── test_models.py
├── integration/             # Tests with external dependencies
│   ├── test_database.py
│   └── test_api_client.py
├── e2e/                     # End-to-end workflows
│   └── test_user_flows.py
├── fixtures/                # Test data files
│   ├── sample_config.yaml
│   └── test_data.json
└── conftest.py              # Root-level configuration

Related Resources

  • Agent: Use python3-development:python-pytest-architect for test implementation
  • Skill: python3-development for general Python patterns
  • Command: /python3-development:modernpython for modern Python syntax reference
Stats
Parent Repo Stars30
Parent Repo Forks4
Last CommitMar 23, 2026