Mutation testing setup
Skill StefanTheCode/dotnet-ai-toolkit/skills/mutation-testing-setup
Set up mutation testing with Stryker.NET to measure whether tests actually catch bugs, and interpret the mutation score and surviving mutants. Use this skill whenever the user wants mutation testing, Stryker, to know if their tests are any good, test quality beyond coverage, surviving mutants, or asks "are my tests actually testing anything / mutation score / Stryker setup". Always use this skill for mutation-testing requests; it configures Stryker and explains the results.From its SKILL.md
npx -y skills add StefanTheCode/dotnet-ai-toolkit --skill mutation-testing-setupAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 18 stars18 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
2.4 KB, as published. Nobody here has run it
Mutation Testing Setup (Stryker.NET)
Measure whether your tests actually catch bugs — not just execute code — with Stryker.NET, and turn surviving mutants into better tests.
Input — point it at your project
Works on a target: a project/test project or GitHub URL. Find the test project: find <target> -iname "*.Tests.csproj".
Setup
dotnet tool install -g dotnet-stryker
cd path/to/Tests.Project
dotnet stryker
stryker-config.json (scope it so runs are fast):
{
"stryker-config": {
"project": "MyApp.csproj",
"test-projects": ["MyApp.Tests.csproj"],
"mutate": ["**/Core/**/*.cs", "!**/Migrations/**"],
"thresholds": { "high": 80, "low": 60, "break": 50 }
}
}
Reading results
- Mutation score = killed mutants / total. Higher = tests catch more injected bugs.
- Surviving mutant = Stryker changed the code (e.g. flipped
>to>=, removed a statement) and no test failed → a real gap in your assertions. - Timeout/no-coverage mutants = code not exercised at all (a coverage gap, see
test-coverage-gap-finder).
For each meaningful survivor: add or strengthen an assertion so the mutation would be caught. A test that runs code without asserting its effect lets mutants survive.
Principles
- Coverage says code ran; mutation says tests would catch a bug. Mutation is the truer quality signal.
- Scope mutation runs to important code (it's slow) — don't mutate the whole solution every CI run.
- Don't chase 100% — focus survivors in critical logic.
- Treat survivors as "missing assertion", not "add a test for coverage".
How to use it & best prompts
"Set up Stryker mutation testing", "are my tests actually catching bugs", "explain these surviving mutants", "improve my tests so these mutants die". Pairs with test-coverage-gap-finder and xunit-test-generator.