From mutation-test-runner
Runs mutation tests with Stryker, mutmut, PITest, or go-mutesting to evaluate test suite effectiveness by generating code mutants and verifying test detection. Identifies gaps in test coverage.
npx claudepluginhub jeremylongshore/claude-code-plugins-plus-skills --plugin mutation-test-runnerThis skill is limited to using the following tools:
Execute mutation testing to evaluate the effectiveness of a test suite by systematically introducing small code changes (mutants) and checking whether existing tests detect them. A killed mutant means the tests caught the change; a surviving mutant reveals a testing gap.
Validates test effectiveness using mutation testing with Stryker for TypeScript/JavaScript (Vitest/Jest) and mutmut for Python to identify weak tests.
Runs mutation testing to verify tests catch bugs by introducing mutants into code and checking if tests fail. Extends ATDD workflow as third validation after green acceptance and unit tests.
Runs mutation testing on test suites using stack-specific tools like Stryker (JS), Infection (PHP), Mutmut (Python), and go-mutesting (Go) to validate test quality. Use for verifying test effectiveness.
Share bugs, ideas, or general feedback.
Execute mutation testing to evaluate the effectiveness of a test suite by systematically introducing small code changes (mutants) and checking whether existing tests detect them. A killed mutant means the tests caught the change; a surviving mutant reveals a testing gap.
stryker.config.mjs with mutate patterns, test runner, and thresholds.setup.cfg or pyproject.toml with [mutmut] section.npx stryker run, mutmut run, or mvn pitest:mutationCoverage.| Error | Cause | Solution |
|---|---|---|
| Mutation run takes hours | Too many files in scope or slow test suite | Narrow mutate scope to critical modules; use --incremental mode; parallelize with --concurrency |
| All mutants survive | Tests only check for truthiness, not specific values | Strengthen assertions -- use toBe(42) instead of toBeTruthy(); add boundary checks |
| Equivalent mutant false positive | Mutation produces functionally identical code (e.g., x >= 0 vs x > -1) | Mark as equivalent in config; ignore in score calculation; document rationale |
| Out of memory during run | Too many concurrent mutation workers | Reduce --concurrency setting; increase Node.js --max-old-space-size; reduce shard size |
| Stryker "initial test run failed" | Test suite does not pass cleanly before mutations begin | Fix all failing tests first; ensure npm test exits 0; check test runner configuration |
Stryker configuration for TypeScript project:
// stryker.config.mjs
export default {
mutate: ['src/**/*.ts', '!src/**/*.d.ts', '!src/**/index.ts'],
testRunner: 'jest',
jest: { configFile: 'jest.config.ts' },
reporters: ['html', 'clear-text', 'progress'],
thresholds: { high: 80, low: 60, break: 50 },
concurrency: 4,
timeoutMS: 10000, # 10000: 10 seconds in ms
};
Example surviving mutant and fix:
Mutant: src/utils/discount.ts:15 -- ConditionalExpression
Original: if (total > 100)
Mutant: if (total >= 100)
Status: SURVIVED
Fix -- add boundary test:
it('does not apply discount at exactly 100', () => {
expect(calculateDiscount(100)).toBe(0);
});
it('applies discount above 100', () => {
expect(calculateDiscount(101)).toBe(10.1);
});
mutmut for Python:
# Run mutation testing
mutmut run --paths-to-mutate=src/ --tests-dir=tests/
# View surviving mutants
mutmut results
# Inspect a specific mutant
mutmut show 42