Mutation Testing
Critical rules
- Coverage = execution. Mutation = detection. Prefer Stryker over manual mutation for JS/TS.
- Run at the PR-readiness / end-of-phase gate — never inside each RED-GREEN increment.
- Diff-scoped runs for branches; full runs for setup, CI, or baseline work.
- Mutate production source only — never tests, fixtures, snapshots, generated,
.d.ts, build output. - Every survivor: kill with a behavior test, classify equivalent, or ask the user.
- New tests must fail against the mutant for the right reason before restoring production code.
- Assert exact observable behavior — not
toBeDefined/ weak inequalities. - Before operators, survivors, or WRONG/CORRECT examples, read the matching resource below.
Workflow
- Inspect — Find package manager, runner, Stryker config;
git diff <base>...HEAD --name-only. Monorepo: smallest affected package first. - Setup if missing —
npm init stryker@latest; Vitest plugin;coverageAnalysis: perTest; mutatesrc/**/*.tsexcluding tests. Add scripts:mutation,mutation:incremental,mutation:diff. Before editing config details, read references/setup.md. - Run — Prefer
mutation:difffor branch feedback. Fullmutationfor first setup / shared infra / CI gates. - Triage — Killed: ok. Survived: strengthen the assertion or change the input (equal original/mutant results for the current input means no assertion can kill it), unless equivalent. No Coverage: add behavior test. High-value code (money, permissions, safety): fix immediately. Subtle/unspecified: ask user with concrete choices.
- Kill survivors (TDD) — Keep mutant → write smallest failing behavior test → restore code → verify pass → re-run scoped mutate then diff. Assert returns, persisted state, events — not implementation details.
- CI — Start report-only; add failing thresholds after a baseline. Persist HTML/clear-text artifacts. Incremental locally; force full periodically.
During RED (cheap): use mutator heuristics mentally — see references/mutator-rules.md. Manual fallback only when Stryker can't target the code.
Resources
- references/mutator-rules.md — operators, heuristics, equivalent mutants, manual procedure. Read when planning tests or triaging survivors.
- references/setup.md — Stryker config, scripts, diff scoping. Read when adding or tuning the harness.
- references/examples.md — weak coverage vs boundary-killing tests. Read when strengthening survivors.
Validation
- [ ] Harness is Stryker (or documented manual fallback)
- [ ] Run timed at PR gate, not per TDD increment
- [ ] Diff-scoped for the branch; mutate production only
- [ ] Survivors killed, marked equivalent, or escalated to user
- [ ] Killer tests failed against the mutant first; assert exact behavior
Constraints
- Not for authoring first tests (
writing-tests) or load/chaos (performance-testing). - Adjacent:
tdd-workflow(cycles before this gate),testing-strategy(pyramid placement),verification-before-completion(include mutation report in evidence).