Regression Test Writer
Turn a reported bug into the smallest test that fails for the real reason before the fix and passes afterward. Use when reproducing a defect, reviewing a bug fix with no guard test, converting an incident into permanent coverage, or preventing a previously fixed edge case from returning.
npx agentscamp add skills/regression-test-writerInstall to ~/.claude/skills/regression-test-writer/SKILL.md
Converts a bug into a durable regression test by tracing the real failure path, choosing the lowest reliable test layer, reproducing the defect against the pre-fix behavior, and asserting the user-visible invariant rather than the implementation. It proves red before green, avoids oversized fixtures and mocks, and reports the exact command and failure signal.
Produce a minimal, trustworthy test that fails on the bug and protects the behavior after the fix.
Workflow
- Restate the invariant. Convert the report into one sentence: under input and state X, behavior Y must occur and Z must not occur. Separate symptoms from the actual contract.
- Trace the failing path. Read the production code, existing tests, logs, issue text, and recent changes. Identify the smallest entry point that still crosses the component responsible for the failure.
- Choose the lowest reliable layer. Prefer unit, then component/integration, then contract, then end-to-end. Do not choose a low layer if mocks remove the database, serializer, concurrency, timezone, or framework behavior that caused the bug.
- Minimize the fixture. Keep only state required to trigger the defect. Use existing builders and factories. Replace timestamps, randomness, network, and concurrency with controlled inputs without changing the failure mechanism.
- Write the test against behavior. Name the bug condition and expected outcome. Assert outputs, persisted state, side-effect count, or observable error—not private method calls or incidental implementation.
- Prove the test is red. Run the focused test against the broken state when available. Confirm it fails at the intended assertion, not from setup, missing dependencies, or an unrelated error. Record the failure signal.
- Apply or verify the fix. If the requested scope includes implementation, make the smallest fix and rerun. Otherwise leave the failing test and report that it correctly reproduces the bug.
- Check for false confidence. Temporarily weaken or remove the production fix when safe, or otherwise demonstrate the test distinguishes broken from correct behavior. Run the relevant surrounding suite to catch fixture pollution.
WARNING
A test that was never observed failing may document the fixed implementation without guarding the defect. Prove red for the expected reason before trusting green.
Output
Report:
- the behavioral invariant and chosen test layer
- the new or updated test file
- the focused command used to reproduce it
- red-state evidence: expected assertion and observed failure
- green-state and surrounding-suite results when a fix is present
- any part of the original report that could not be reproduced
Frequently asked questions
- Should a regression test be written before the bug fix?
- Yes whenever the defect can be reproduced safely. Seeing the new test fail for the expected reason proves it covers the bug; a test written after the fix can pass without ever exercising the broken behavior.
- At what level should a regression test live?
- Use the lowest layer that reproduces the real failure without mocking away its cause. Pure logic belongs in a unit test, database or framework behavior in an integration test, interface incompatibility in a contract test, and only genuinely cross-system failures in end-to-end tests.
Related
- 9 Best Claude Skills for Software TestingCompare Claude skills for regression, unit, integration, contract, property, mutation, prompt, and test-data workflows.
- Test ScaffolderScaffold a test file with sensible cases for a given module or function. Use when adding tests to untested code and you want a fast, structured starting point.
- Coverage Gap FinderRun the project's coverage tool and identify the highest-value untested paths — error branches, edge cases, and critical modules — then propose specific test cases for each gap. Use when you have a coverage report but don't know where new tests will pay off most.
- Integration Test DesignerDesign integration tests that exercise components against REAL collaborators — actual database, queue, HTTP boundary — at a deliberately chosen seam, instead of a unit suite that mocks everything or a slow flaky full E2E. Use when bugs slip past green unit tests, when wiring or contracts between layers break in production, or when a mocked DB test passes but the real query/migration/serialization fails.
- Contract Test DesignerDesign consumer-driven contract tests between services so an API provider can't break its consumers unnoticed — without slow, flaky full end-to-end environments. Use when independent services or teams integrate over an API, when integration bugs only surface in staging or prod, or when E2E suites are too slow and brittle to catch breaking API changes.
- Fix Failing TestDiagnose and fix a failing test by finding the real root cause.