Mutation Score Improvement Workflow
Use mutation testing to find assertions that do not actually detect bugs and strengthen them where it matters.
Objective
Improve the strength of test assertions by measuring mutation score.
Environment
- A mutation testing tool
- Core modules to target
- A coverage baseline
Steps
1. Run mutation testing on critical modules
Generate mutants for the modules whose correctness matters most.
Expected state: A mutation score and surviving mutants list exists.
2. Analyse survivors
Find mutants that survive and identify the missing or weak assertions.
Expected state: Weak assertions are located.
3. Strengthen assertions
Add or tighten assertions to kill the important surviving mutants.
Expected state: The mutation score rises for meaningful mutants.
4. Track the score
Track the mutation score over time as a quality signal, not a gate
Expected state: Test strength trends up.
Decision points
Gate on mutation score?
- Track as a signal, not a hard gate
- Hard gate the score
Track the score; hard gates on mutations slow CI and can be gamed.
All code or core modules?
- Focus on core modules
- All code
Focus on core modules where correctness is critical.
Expected outcome
Tests detect real defects better, measured by a rising mutation score on critical modules.
Verification
Confirm previously surviving mutants are now killed and the score improved on the targeted modules.
Cleanup
Record the score baseline and revisit after significant refactors.
Overview
Improve the strength of test assertions by measuring mutation score.
This workflow is reusable across teams and environments; adapt the commands to your tooling while keeping the sequence and checkpoints intact.
Environment and prerequisites
- A mutation testing tool
- Core modules to target
- A coverage baseline
Procedure
1. Run mutation testing on critical modules
Generate mutants for the modules whose correctness matters most.
Expected state: A mutation score and surviving mutants list exists.
2. Analyse survivors
Find mutants that survive and identify the missing or weak assertions.
Expected state: Weak assertions are located.
3. Strengthen assertions
Add or tighten assertions to kill the important surviving mutants.
Expected state: The mutation score rises for meaningful mutants.
4. Track the score
Track the mutation score over time as a quality signal, not a gate
Expected state: Test strength trends up.
# run mutation testing on a module
npx stryker run --mutate 'src/**/*.ts'
Verification
Confirm previously surviving mutants are now killed and the score improved on the targeted modules.
Decision points
Gate on mutation score?
- Track as a signal, not a hard gate
- Hard gate the score
Recommendation: Track the score; hard gates on mutations slow CI and can be gamed.
All code or core modules?
- Focus on core modules
- All code
Recommendation: Focus on core modules where correctness is critical.
Common failures
- High coverage with weak assertions gives false confidence.
- Gating on score slows CI without value.
- Mutating everything wastes time.