Measure how strong a test suite is by mutating the code and checking the tests notice, exposing assertions that never actually fail. Use when coverage is high but you doubt the tests would catch a real regression.
Scanned 9/5/2026
Install to Claude Code
npx -y skills add Amey-Thakur/AI-SKILLS --skill mutation-testing --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Mutation Testing?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/amey-thakur-mutation-testing)More formats (shields.io, HTML) on the badges page.
---
name: mutation-testing
description: Measure how strong a test suite is by mutating the code and checking the tests notice, exposing assertions that never actually fail. Use when coverage is high but you doubt the tests would catch a real regression.
---
# Mutation testing
Line coverage tells you a line ran, not that a test would fail if the line
were wrong. Mutation testing closes that gap: a tool makes small changes to
the code, flips a `<` to `<=`, replaces a return with a constant, deletes a
call, then reruns the suite. A mutant the tests kill proves they guard that
behavior. A mutant that survives is a hole coverage could not see, a line
executed but never truly asserted.
## Method
1. **Run a mutation tool for your stack.** Stryker for JavaScript and C#, PIT
for the JVM, mutmut or cosmic-ray for Python, cargo-mutants for Rust. Point
it at the module whose tests you distrust, not the whole repo on the first
pass.
2. **Read the mutation score as a diagnostic, not a target.** The score is
killed mutants over total. Chasing 100% burns effort on equivalent
mutants, changes that cannot alter behavior. Treat survivors as a reading
list, not a number to maximize.
3. **Kill survivors by strengthening assertions.** A survivor usually means a
test ran the line but asserted nothing about its effect. Add the assertion
that pins the boundary the mutant moved, for instance `<=` versus `<` at a
threshold.
4. **Recognize equivalent mutants and move on.** Some mutants leave behavior
identical: reordering commutative operations, a timeout the tests cannot
observe. Mark them ignored with a reason rather than contorting a test to
kill something untestable.
5. **Scope runs to survive the cost.** Mutation testing reruns the suite once
per mutant and is slow. Restrict it to changed files in CI with a
`--since` diff mode, or run a full sweep on a schedule against critical
modules.
6. **Gate only the code that matters.** For a payment or auth core, fail the
build when new survivors appear. Elsewhere, run it periodically to find
rotted tests instead of blocking every commit.
## Signals
- Do surviving mutants cluster on branches the team assumed were tested?
- After you kill a survivor, does the new assertion fail if you reintroduce
the original bug by hand?
- Is the runtime scoped so mutation testing informs work rather than blocking
it?
## Boundaries
Mutation testing grades an existing suite, it does not write tests or choose
what to cover: pair it with unit-test-design to fill the holes it finds.
Equivalent mutants and runtime cost make it a periodic audit for critical
code, not a gate on every file.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!