Copy-paste Claude Code prompts for pytest — fixture design, parametrize, factory-boy, async tests, and avoiding test interdependence. Python 3.12 ready.
pytest's flexibility is its weakness from Claude's perspective — too many valid styles. Pinning the fixture style, the mocking library, and the parametrize policy makes Claude's output consistent across the codebase.
Write tests for app.utils.dates.business_days_between(start, end) at
tests/utils/test_dates.py.
Cases to cover:
- Same day → 0
- One business day apart → 1
- Weekend skipped (Friday to Monday) → 1
- Across a US public holiday (Labor Day 2026) → expected number minus 1
- Reversed (end < start) → ValueError
- Timezone-aware dates in non-UTC zones → result correct
Constraints:
- Use @pytest.mark.parametrize with the ids= kwarg so failure messages name
the case (e.g. id='friday_to_monday').
- One @pytest.mark.parametrize per logical group — happy paths, edges, errors
as three separate decorators or three separate test functions.
- For the error case, use pytest.raises(ValueError, match='start must be...').
- No conftest changes; this is pure logic.
- Read tests/utils/test_strings.py first to match the style.
Write an integration test for POST /api/projects at tests/api/test_projects.py.
Fixtures needed:
- async_client (function-scoped) — httpx.AsyncClient pointing at the FastAPI
test app. Read tests/conftest.py — async_client already exists, reuse it.
- authenticated_user (function-scoped) — creates a user, returns
(user, headers_with_bearer).
- session (function-scoped) — async SQLAlchemy session bound to a fresh
transaction that rolls back on teardown.
Tests:
- test_create_project_201
- test_create_project_validation_400 (missing name)
- test_create_project_duplicate_slug_409
- test_create_project_anon_401
Constraints:
- No global state — every fixture function-scoped, transactional rollback.
- Use factory_boy factories from tests/factories/ for any seed data.
- Use httpx — never requests.
- Async tests with @pytest.mark.asyncio (or rely on auto mode if configured).
- One assertion per test, plus assertions on status_code.
tests/services/test_notifications.py::test_email_sends_on_signup is flaky
(fails ~5% of CI runs). Read the file + the conftest.
Identify potential causes:
- Test ordering dependency: any module-level state, shared fixture, or class-level fixture?
- Real network call: anything that hits a non-localhost URL?
- Time dependency: now()/timezone.now() called without freeze?
- Race condition: any threading/asyncio without await/join?
- Filesystem state: temp files in /tmp without cleanup?
For each potential cause, cite the file:line and write 1 sentence on why
it could cause flake. Then propose the minimum fix.
Do NOT change the code yet — output the analysis first.
## pytest policy
- Python 3.12, pytest 8, pytest-asyncio (mode=auto), factory_boy, freezegun,
pytest-randomly enabled — tests must pass in any order.
- Fixtures default to function-scope. Session-scope requires a comment
justifying it.
- No mocks of HTTP — use respx for httpx, responses for requests.
- One assert per test outside of status checks. Multi-assert tests get
parametrized or split.
- Test names: test___.
Related: testing the Claude API.