From ct
Runs diff-scoped mutation testing to verify test quality beyond coverage metrics. Detects language and selects Stryker, mutmut, cargo-mutants, PIT, or gremlins.
How this skill is triggered — by the user, by Claude, or both
Slash command
/ct:mutation-testingThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Diff-scoped mutation testing: systematically verify that your tests catch real bugs by introducing small code changes (mutations) and checking if the test suite detects them.
Diff-scoped mutation testing: systematically verify that your tests catch real bugs by introducing small code changes (mutations) and checking if the test suite detects them.
Always diff-scoped. Full-project mutation testing is impractical interactively. This skill scopes to changed code by default.
Detect the project language and select the mutation testing tool.
| Project File | Language | Tool | Interactive Viability |
|---|---|---|---|
package.json + *.ts/*.js | JavaScript/TypeScript | Stryker | High — line-range targeting, incremental mode |
pyproject.toml / setup.py | Python | mutmut | Medium — file-level targeting only |
Cargo.toml | Rust | cargo-mutants | High — --in-diff flag, function targeting |
pom.xml / build.gradle | Java/Kotlin | PIT | Medium — class-level targeting |
go.mod | Go | gremlins | Low — pre-1.0, limited targeting |
If multiple languages detected: ask the user which to target. If no supported language: STOP: "No mutation testing tool available for this project's language." If Go detected: warn: "Go mutation testing uses gremlins (pre-1.0). Results may be limited."
Check if the selected tool is installed. If not, offer to install.
Refer to references/tool-install-patterns.md for per-language install commands.
Check if tool exists:
npx stryker --version (project-local preferred)command -v mutmutcommand -v cargo-mutantspom.xml/build.gradle for pitest plugincommand -v gremlinsIf missing → ask user:
<tool> not found. Install it?
Y) Install now (<install command>)
N) Skip mutation testing
Install using the commands in the references doc.
Determine which code to mutate. Always prefer the narrowest scope.
Scope resolution (priority order):
git diff --cached --name-only + line ranges from git diff --cachedgit diff --name-only + line ranges from git diffgit diff HEAD~1 --name-only + line ranges from git diff HEAD~1Extract file paths and line ranges from the diff:
# Get changed files (filter to source code, exclude tests)
git diff --name-only | grep -v -E '(test|spec|__test__)' | head -20
# Get line ranges per file
git diff --unified=0 <file> | grep '^@@' | sed -E 's/.*\+([0-9]+)(,([0-9]+))?.*/\1-\1+\3/'
Report: "Targeting 3 changed files: src/utils.ts (lines 10-35), src/pricing.ts (lines 40-55), src/auth.ts (lines 12-28)"
Before running, estimate the work and warn if it will be slow.
Per-tool dry run:
npx stryker run --mutate "<file>:<lines>" --dryRun (parse output for mutant count)cargo mutants --in-diff <(git diff) --list --json | jq lengthSpeed guardrails:
~85 mutants detected. Estimated time: 5-10 minutes.
A) Run all
B) Narrow scope — specify a function or line range
C) Cancel
Execute the mutation testing tool with appropriate flags.
Stryker (JS/TS):
npx stryker run \
--mutate "src/utils.ts:10-35" \
--reporters json,progress \
--incremental \
--incrementalFile .stryker-incremental.json \
--concurrency $(( $(nproc 2>/dev/null || sysctl -n hw.ncpu) - 1 ))
Output: reports/mutation/mutation.json
mutmut (Python):
mutmut run --paths-to-mutate src/utils.py
mutmut results
mutmut show all
Output: .mutmut-cache SQLite database
cargo-mutants (Rust):
cargo mutants \
--in-diff <(git diff HEAD~1) \
--json \
--baseline=skip \
-j $(( $(nproc 2>/dev/null || sysctl -n hw.ncpu) ))
Output: mutants.out/outcomes.json
PIT (Java — Maven):
mvn pitest:mutationCoverage \
-DtargetClasses="com.example.Utils" \
-DoutputFormats=XML \
-Dthreads=$(( $(nproc 2>/dev/null || sysctl -n hw.ncpu) )) \
-DhistoryInputLocation=target/pit-history.bin \
-DhistoryOutputLocation=target/pit-history.bin
Output: target/pit-reports/*/mutations.xml
gremlins (Go):
gremlins unleash --tags "src/utils.go"
Output: text to stdout
Parse the tool output and categorize each mutant.
Mutant categories:
For mutmut: filter results to only show mutations within the diff line range (mutmut targets whole files).
Present summary first:
Mutation Score: 78% (45/58 killed, 10 survived, 3 no coverage)
Then present each surviving mutant with a fix suggestion:
SURVIVING MUTANTS (tests didn't catch these):
[SURVIVED] ConditionalBoundary — src/utils.ts:24
Mutation: changed `age >= 18` → `age > 18`
Why it matters: Edge case at exact boundary value (age=18) is not tested
Suggested test:
expect(isAdult(18)).toBe(true) // boundary: exactly 18
expect(isAdult(17)).toBe(false) // just below boundary
[SURVIVED] ArithmeticOperator — src/pricing.ts:42
Mutation: changed `price * quantity` → `price / quantity`
Why it matters: Core business logic — no test verifies the actual calculation result
Suggested test:
expect(calculateTotal(10, 3)).toBe(30) // verify multiplication, not just non-null
[NO COVERAGE] — src/auth.ts:20-28
Function `validateToken` has no test coverage
Suggested: Add test verifying token validation returns true for valid tokens
and false/throws for expired, malformed, or missing tokens
MUTATION TESTING SUMMARY
Tool: Stryker (JS/TS)
Scope: 3 files, 58 mutants (diff-scoped)
Score: 78% (45 killed, 10 survived, 3 no coverage)
Test improvements needed:
1. Add boundary value tests for age/date comparisons (3 surviving mutants)
2. Assert exact calculation results, not just non-null (4 surviving mutants)
3. Add tests for validateToken function (3 no-coverage mutants)
Re-run after adding tests to verify improvement.
superpowers:test-driven-development: Validates that TDD tests are strong, not just greenbugmagnet: Quantifies how weak the tests are when bugmagnet identifies gapsct:fix-loop: Optional verification — after fixing review findings, run mutations on changed codenpx claudepluginhub pvillega/claude-templates --plugin ctPerforms mutation testing using Claude as the mutation engine: generates code mutants, runs tests, tracks kill/survive rates, identifies test gaps, and recommends test improvements. No external mutation tools required.
Runs mutation testing workflow: mutates source code module-by-module, executes tests per mutation, writes tests for survivors, verifies, commits. Tracks multi-session progress.
Runs mutation testing on changed files to verify AI-generated test quality, computes kill score, and optionally auto-fixes surviving mutants.