| name | prune_tests |
|---|---|
| description | Review the tests added on the current feature branch and cut the low-value ones, weighing each test's protection against its maintenance cost. Use when the user asks to "cut tests", "prune tests", "review the tests", "are these tests worth keeping", "trim the test suite", or wants to reduce test maintenance before opening/merging a PR. Applies the project's CLAUDE.md testing guidance. |
Every test has a carrying cost: it runs on every CI pass and must be maintained when the code changes. Keep a test only when the protection it gives outweighs that cost. This skill reviews the tests this branch added and recommends which to cut.
A test earns its place when it guards real business logic or a code path that could plausibly regress and isn't already covered elsewhere. Cut tests that test the framework, test trivial passthrough, or duplicate a path another test already exercises.
This mirrors the project's CLAUDE.md guidance — do NOT write (or keep) tests for:
- Django/framework built-in behavior (default field values, choice validation,
get_object_or_404returning 404, aCharFieldstoring what you passed it) - Trivial field passthrough (asserting a value was stored when it's just handed to
objects.create()) - Duplicate code paths already covered by another test (the same branch/condition reached two ways)
-
Find the tests this branch added (vs.
master):git diff master...HEAD -- '*test*' '*tests*'
Read the full diff of every added/modified test, not just the names — you need each test's assertions to judge it.
-
List every added test method so the review is exhaustive:
git diff --name-only master...HEAD -- '*test*' | xargs grep -n "def test_"
-
Classify each test as KEEP or CUT, with a one-line reason. Use this rubric:
KEEP — the test pins logic that could break and isn't covered elsewhere:
- Non-trivial branching / conditions you wrote (dedup, guards, filters, ordering)
- Deliberate design decisions a future change could silently violate (append-only, "only emit on X", privacy/no-leak, access control, result hiding)
- Regression guards for a specific bug you just fixed (reference the bug in the test comment)
- Error-handling you deliberately added (e.g. "failure in X must not break critical path Y")
- One representative happy-path smoke test per view/endpoint
CUT — cost outweighs value:
- Tests framework behavior (404 from
get_object_or_404, redirect fromlogin_required, field defaults) - Near-trivial rendering assertions ("this string appears in the HTML") with no logic behind them
- A second test of the same branch/condition another test already covers (e.g. the zone half of an
is_top or is_zoneguard when the top half is tested; dedup via path B when path A already proves the dedup function) - Defensive scaffolding nothing reaches in practice (e.g.
assertRaises(NotImplementedError)on a guard no caller hits)
When two tests pin the two sides of a single boolean cheaply (e.g.
is_flashTrue and False), it's fine to keep both — that's documenting one branch, not duplicating two. -
Present the classification to the user for confirmation before deleting. "Valuable" is partly a judgment call and the user knows the maintenance context. Show a compact table (test name → KEEP/CUT → reason) or use an AskUserQuestion multi-select listing the CUT candidates. Do not delete until the user confirms which to cut.
-
Remove the confirmed tests. After deleting:
- Check for now-unused imports/helpers in the test file and remove them (grep each imported symbol; if it has zero remaining uses, drop the import). A shared
setUp/helper used only by a deleted test should go too. - Don't leave a now-empty test class.
- Check for now-unused imports/helpers in the test file and remove them (grep each imported symbol; if it has zero remaining uses, drop the import). A shared
-
Run the affected test files and
manage.py checkto confirm the remaining suite is green:uv run python manage.py test <app>.tests.<module> ... uv run python manage.py check
-
Commit with a message that lists what was cut and why, and notes what was deliberately kept. One commit for the pruning.
- Only prune tests added on this branch unless the user explicitly asks to review existing tests too — don't expand scope into unrelated test cleanup.
- If a "CUT" candidate is the only thing covering a real path, it's a KEEP — re-check before recommending the cut.
- Keep the user's final call authoritative: if they want to keep something you'd cut (or vice versa), follow them.