Alpha. Vary is under active development and not ready for production use. Syntax, APIs, performance, and behaviour may change between releases.
Equivalent mutants
Some mutants produce the same observable behaviour as the original program. No test can kill them because there is no difference to detect. These are equivalent mutants, and they inflate the survivor count without representing real test gaps.
Why equivalent mutants exist
A mutation like replacing x + 0 with x - 0 changes the bytecode but not the result. The mutant is alive but unkillable. Other examples:
| Example | Why it is equivalent |
|---|---|
| Negating a variable that is always zero | x and -x are both 0 |
Removing a print() call in code where output is not tested | No oracle checks stdout |
| Changing a comparison in a branch that is never reached | Dead code, no observable effect |
Every mutation testing tool has this problem. Vary uses heuristics to identify likely-equivalent mutants so they do not distort your score.
Suspicion heuristics
The equivalence analyzer scores each surviving mutant with multiple independent signals:
| Heuristic | Confidence | What it detects |
|---|---|---|
bytecode_identical | 1.0 | Mutant bytecode is identical to original (already flagged by bytecode comparison) |
trivial_arithmetic | 0.85 | Identity-preserving arithmetic: x + 0, x * 1, x - 0 patterns |
dead_branch | 0.7 | Mutant survived with zero execution time (code path never reached) |
semantic_noop | 0.6 | Statement removal of side-effect-only calls like print() or log() |
untested_path | 0.4 | Mutant is in a code region with no test coverage at all |
The overall confidence is the maximum signal confidence. Multiple signals reinforce the diagnosis but do not stack numerically.
Confidence levels and recommendations
| Confidence | Recommendation |
|---|---|
| 0.9 to 1.0 | Quarantine automatically (almost certainly equivalent) |
| 0.6 to 0.89 | Review recommended, likely equivalent but worth checking |
| 0.4 to 0.59 | Investigate: may be a real test gap in untested code |
Auto-quarantine
Use --auto-quarantine <threshold> to automatically quarantine mutants above a confidence level:
vary mutate src/ --auto-quarantine 0.9
This quarantines high-confidence equivalent mutants without manual review. Quarantined mutants are excluded from the mutation score and survivor lists. They are stored in .vary/equivalent-mutants.json and can be reviewed or restored:
vary mutate src/ --list-quarantined
vary mutate src/ --unquarantine "mutant-id"
Impact on scoring
Equivalent-likely mutants affect the actionable survivor rate but not the kill rate:
| Metric | Includes equivalent-likely? |
|---|---|
| Kill rate | No (denominator includes them) |
| Observability | No |
| Actionable survivor rate | No (subtracted from survivors) |
The actionable survivor rate is the metric to watch: it excludes likely-equivalent mutants so you focus on survivors worth investigating.
What to do next
| Page | Topic |
|---|---|
| Infrastructure | Quarantine management, policy gates, CLI reference |
| Lie detection | Find tests that pass but check nothing |
| Advanced overview | How equivalent mutant handling fits the six-pillar model |