Mutation Testing Knowledge Base
Distilled from the primary sources, the foundational papers, the industrial-scale reports, and the
tool documentation that defines the vocabulary everyone else borrows. Reference files in
reference/ are source-attributed; this file routes and answers the common questions without a load.
Routing Table
| Query about... |
Load |
| Mutant states (killed/survived/no-coverage/timeout), operator catalogs, what a mutation actually is |
operators-and-states.md |
| Mutation score, covered-code score, test strength, MSI, the oracle gap, what to report |
metrics.md |
| Cost, diff-scoping, arid nodes, productive vs unproductive mutants, suppression, why not to gate |
scaling-and-suppression.md |
| Which tool for which ecosystem, what each supports, what to do when no tool exists |
tooling.md |
| Equivalent mutants, coupling effect, competent programmer hypothesis, the theory |
theory.md |
Quick decision guide (no load required)
"What is mutation testing?". Coverage tells you a line executed. It cannot tell you the line
was checked. Mutation testing introduces a small deliberate fault (a mutant), re-runs the
tests, and observes: tests fail → the mutant is killed, something genuinely asserted on that
behavior; tests pass → the mutant survived, that line ran and nothing noticed it was wrong. The
mutation is always reverted; the source is unchanged at the end.
"Is it just better coverage?". It answers a different question. Coverage measures execution;
mutation testing measures fault detection. PIT states it directly: line coverage "does not check
that your tests are actually able to detect faults." A file at 100% coverage and 40% mutation
score has tests that run the code and assert almost nothing about it.
"Which number do I look at?". The covered-code one, always. Plain mutation score mixes two
unrelated problems: "my tests are weak" and "I have no tests here." The covered-code variant
(PIT calls it test strength, Infection calls it Covered Code MSI) isolates the first. A wide gap
between the two means the coverage you have is thin, not that the tests are bad.
"Should we fail the build on a mutation score?". No, and this is the single most common way
adoption fails. The score is depressed by equivalent mutants that no test can ever kill, so a hard
threshold rewards suppressing mutants over writing tests. Report it; do not gate on it.
Scaling and suppression mechanics: see scaling-and-suppression.md.
"Isn't this too slow to be practical?". Naive whole-repo mutation testing is, and that is why
the technique sat unused for thirty years. The industrial answer is architectural, not
computational: mutate only the changed lines, at most one mutant per line, suppress
uninteresting nodes, and surface the result as a review-time prompt rather than a report. Google
reports a median of 7 mutants per changelist under that regime against 820 for traditional
mutagenesis.
"A mutant survived. Now what?". Three possible answers, and telling them apart is the whole
skill:
- Productive, a real gap. Write a test that kills it.
- Equivalent, the mutated program is semantically identical to the original, so no test can
kill it. Not a defect, not a suppression; the check itself is wrong for that node.
- Arid. Killable, but killing it would not improve the suite (a log line, a trivial
accessor). Suppress it with a written reason.
"Why can't the tool tell me which?". Deciding equivalence is undecidable in general
(Jia & Harman). That is why the classification is a judgment step, and why
/mutation-testing:audit delegates it to a fresh context rather than to the context that authored
the tests.
What this skill does NOT do
- Run a mutation tool. That is
/mutation-testing:audit.
- Install or configure one. That is
/mutation-testing:setup.
- Answer general test-design questions (mocking, four pillars, classical vs London). Those belong to
/tdd:principles when the tdd plugin is installed; without it, consult your project's own
test-design guidance.
- Explain what a coverage, CRAP, or complexity number can and cannot say on its own. Those
cross-metric caveats belong to
/code-metrics:principles when the code-metrics plugin is
installed; without it, hold to the one rule this skill does own: coverage records execution,
not detection, and no coverage figure substitutes for a mutation score.
1---2name: principles-33description: Answers mutation-testing questions from the primary literature (DeMillo/Lipton/Sayward, Jia & Harman, Google's ICSE-SEIP papers, and the Stryker/PIT/Infection tool docs), producing WHY reasoning about what a surviving mutant means. Use when: the user asks what mutation testing is or whether it is worth doing, asks how the score relates to coverage ('mutation score vs coverage', 'what is test strength'), asks what a mutant's state or disposition means ('equivalent mutant', 'what is an arid node'), asks which operators to use or why a score is low, asks whether to gate a build on the score, or names the underlying theory ('coupling effect', 'competent programmer hypothesis'); not for HOW to run a mutation tool in your project (use `/mutation-testing:setup` and `/mutation-testing:audit`).4---56# Mutation Testing Knowledge Base78Distilled from the primary sources, the foundational papers, the industrial-scale reports, and the9tool documentation that defines the vocabulary everyone else borrows. Reference files in10`reference/` are source-attributed; this file routes and answers the common questions without a load.1112## Routing Table1314| Query about... | Load |15|---|---|16| Mutant states (killed/survived/no-coverage/timeout), operator catalogs, what a mutation actually is | [operators-and-states.md](reference/operators-and-states.md) |17| Mutation score, covered-code score, test strength, MSI, the oracle gap, what to report | [metrics.md](reference/metrics.md) |18| Cost, diff-scoping, arid nodes, productive vs unproductive mutants, suppression, why not to gate | [scaling-and-suppression.md](reference/scaling-and-suppression.md) |19| Which tool for which ecosystem, what each supports, what to do when no tool exists | [tooling.md](reference/tooling.md) |20| Equivalent mutants, coupling effect, competent programmer hypothesis, the theory | [theory.md](reference/theory.md) |2122## Quick decision guide (no load required)2324**"What is mutation testing?"**. Coverage tells you a line *executed*. It cannot tell you the line25was *checked*. Mutation testing introduces a small deliberate fault (a **mutant**), re-runs the26tests, and observes: tests fail → the mutant is **killed**, something genuinely asserted on that27behavior; tests pass → the mutant **survived**, that line ran and nothing noticed it was wrong. The28mutation is always reverted; the source is unchanged at the end.2930**"Is it just better coverage?"**. It answers a different question. Coverage measures execution;31mutation testing measures *fault detection*. PIT states it directly: line coverage "does **not** check32that your tests are actually able to **detect faults**." A file at 100% coverage and 40% mutation33score has tests that run the code and assert almost nothing about it.3435**"Which number do I look at?"**. The **covered-code** one, always. Plain mutation score mixes two36unrelated problems: "my tests are weak" and "I have no tests here." The covered-code variant37(PIT calls it *test strength*, Infection calls it *Covered Code MSI*) isolates the first. A wide gap38between the two means the coverage you have is thin, not that the tests are bad.3940**"Should we fail the build on a mutation score?"**. No, and this is the single most common way41adoption fails. The score is depressed by equivalent mutants that no test can ever kill, so a hard42threshold rewards suppressing mutants over writing tests. Report it; do not gate on it.43Scaling and suppression mechanics: see [scaling-and-suppression.md](reference/scaling-and-suppression.md).4445**"Isn't this too slow to be practical?"**. Naive whole-repo mutation testing is, and that is why46the technique sat unused for thirty years. The industrial answer is architectural, not47computational: mutate only the **changed lines**, at most **one mutant per line**, suppress48uninteresting nodes, and surface the result as a review-time prompt rather than a report. Google49reports a median of **7 mutants per changelist** under that regime against **820** for traditional50mutagenesis.5152**"A mutant survived. Now what?"**. Three possible answers, and telling them apart is the whole53skill:54551. **Productive**, a real gap. Write a test that kills it.562. **Equivalent**, the mutated program is semantically identical to the original, so no test can57 kill it. Not a defect, not a suppression; the check itself is wrong for that node.583. **Arid**. Killable, but killing it would not improve the suite (a log line, a trivial59 accessor). Suppress it *with a written reason*.6061**"Why can't the tool tell me which?"**. Deciding equivalence is undecidable in general62(Jia & Harman). That is why the classification is a judgment step, and why63`/mutation-testing:audit` delegates it to a fresh context rather than to the context that authored64the tests.6566## What this skill does NOT do6768- Run a mutation tool. That is `/mutation-testing:audit`.69- Install or configure one. That is `/mutation-testing:setup`.70- Answer general test-design questions (mocking, four pillars, classical vs London). Those belong to71 `/tdd:principles` when the `tdd` plugin is installed; without it, consult your project's own72 test-design guidance.73- Explain what a coverage, CRAP, or complexity number can and cannot say on its own. Those74 cross-metric caveats belong to `/code-metrics:principles` when the `code-metrics` plugin is75 installed; without it, hold to the one rule this skill does own: coverage records execution,76 not detection, and no coverage figure substitutes for a mutation score.