From python-engineering
Provides pytest testing patterns, fixture designs, coverage configurations, Hypothesis property-based tests, and mutmut mutation testing for Python projects. Useful for test writing, fixtures, and coverage setup.
How this skill is triggered — by the user, by Claude, or both
Slash command
/python-engineering:python3-testingThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Consult `python3-core` for standing defaults (coverage, test naming, AAA).
Consult python3-core for standing defaults (coverage, test naming, AAA).
Tests are specifications. When a test fails, investigate both possibilities:
| Hypothesis A | Hypothesis B |
|---|---|
| Test expectations are wrong | Implementation has a bug |
| Test is outdated | Test caught a regression |
| Test has wrong assumptions | Test found an edge case |
Red flags: Never immediately change tests to match implementation. Never assume implementation is always correct. Never bulk-update tests without individual analysis.
For the full investigation protocol, red flags, and example responses, load /python-engineering:test-failure-mindset.
from pathlib import Path
from string import Template
FIXTURES_DIR = Path(__file__).parent / "fixtures"
@pytest.fixture
def mock_binary(tmp_path: Path) -> Path:
template_path = FIXTURES_DIR / "binaries" / "mock_binary_template.sh"
template = Template(template_path.read_text())
content = template.substitute(binary_name="tool", version="1.0.0")
binary = tmp_path / "tool"
binary.write_text(content)
binary.chmod(0o755)
return binary
| Code Type | Minimum |
|---|---|
| Business logic | 90% |
| Standard code | 80% |
| Scripts/utilities | 70% |
| Critical paths | 95% + mutation testing |
# pyproject.toml
[tool.coverage.run]
branch = true
source = ["src"]
omit = ["**/tests/**"]
[tool.coverage.report]
fail_under = 80
exclude_lines = [
"pragma: no cover",
"if TYPE_CHECKING:",
"raise NotImplementedError",
]
When Hypothesis is available:
@given(st.from_type(T))from hypothesis import given, strategies as st
@given(st.lists(st.integers()))
def test_sort_maintains_length(data: list[int]) -> None:
"""Sorting preserves all elements."""
result = sorted(data)
assert len(result) == len(data)
For critical code (payments, auth, data validation):
uv run mutmut run --paths-to-mutate=packages/module/
uv run mutmut results
Target: >90% mutation score for critical code paths.
tests/
├── conftest.py # Shared fixtures
├── unit/ # Fast, isolated tests
├── integration/ # Tests with external dependencies
├── e2e/ # End-to-end workflows
└── fixtures/ # Test data files
references/testing-standards.md — full testing standardsreferences/agent-prompts.md — agent test promptsreferences/plan-templates.md — test plan templatesnpx claudepluginhub jamie-bitflight/claude_skills --plugin python-engineeringDesigns pytest test suite architecture, plans coverage strategies, and reviews structure for Python 3.11+ projects. Guides test pyramid, fixtures, parametrization, async testing, and property-based approaches.
Designs pytest test suite architecture and coverage for Python 3.11+ projects: fixtures, parametrization, test pyramid, AAA pattern, unit/integration/E2E strategies.
Guides Python testing with pytest: TDD cycle, fixture patterns, mocking, parametrization, and 80%+ coverage targets. Activates when writing Python tests or setting up coverage infrastructure.