name: mutants
description: "Use when writing or editing tests, or triaging a missed mutant: scoped cargo-mutants runs through cargo x mutants and what to do with each outcome."
Mutants
Test strength, not coverage: which bugs ship because no test notices.
Run
Always through cargo x mutants, always scoped; the wrapper refuses an unscoped run.
Locally it is pinned: one job, nice -n 19, a third of the cores for build and tests, 120 s per mutant, 300 s per build, output under target/mutants.out/.
Those pins are not overridable locally (-j is rejected); --all is CI's and follows its own rules.
cargo x mutants --list -f smith-core/src/session.rs # inventory, no build
cargo x mutants -f smith-core/src/session.rs # one file, while editing tests
jj diff --git > /tmp/d.patch; cargo x mutants -D /tmp/d.patch # changed lines only
cargo x mutants -f smith-core/src/session.rs --iterate # rerun only missed and unviable
cargo x mutants --shard 0/8 # whole tree: one shard per invocation, 0..7
Run cargo x test first; the wrapper skips the baseline.
A shard is 5–10 min; a full tree in one process is what crashed this machine.
Read
missed.txt the worklist
caught.txt healthy
timeout.txt tests hang under the mutation, or the mutation hangs rustc; a finding either way
unviable.txt does not compile; ignore
Triage a miss
- Meaningful behavior → write the test that fails under it (regression-first), rerun with
--iterate. - Not observable → the code is dead or the guard is redundant; delete it.
- Untestable by design (
Debugoutput) →exclude_rein.cargo/mutants.toml, never a#[mutants::skip]dependency. - A miss that needs a production change is a bug: fix it with the test that failed first.
Do not
- Run cargo-mutants directly or with
--in-place. - Raise jobs; narrow the scope.
- Let two runs share
target/mutants.out; one at a time.