Claude Skills Guide

Claude Code Mutation Testing Workflow Guide

Mutation testing evaluates your test suite by introducing small changes (mutations) to your code and checking whether your tests detect them. If a mutation passes your tests, you have a gap in test coverage. This guide shows you how to build a practical mutation testing workflow using Claude Code, the tdd skill, and integration with your existing development process.

Why Mutation Testing Matters

Traditional code coverage tells you which lines execute during tests, not whether those tests actually verify behavior. You can have 90% coverage and still miss critical bugs if your assertions are weak or missing. Mutation testing solves this by creating artificial defects and verifying your test suite catches them.

For example, changing a === b to a !== b should cause at least one test to fail. If your tests still pass, your assertion quality needs improvement. This feedback loop makes your test suite more robust and gives you genuine confidence in your code quality.

Setting Up Mutation Testing in Your Project

Mutation testing requires a dedicated tool. The specific tool depends on your language:

Install Stryker for a JavaScript project:

npm install --save-dev @stryker-mutator/core @stryker-mutator/jest-runner

Create a stryker.conf.json file in your project root:

{
  "mutator": "javascript",
  "packageManager": "npm",
  "reporters": ["html", "clear-text"],
  "testRunner": "jest",
  "jest": {
    "projectType": "create-react-app"
  },
  "thresholds": {
    "high": 80,
    "low": 60,
    "break": 70
  }
}

This configuration runs mutation testing with Jest as the test runner and generates an HTML report showing which mutations survived.

The Claude Code Workflow

Activate the tdd skill in Claude Code to structure your workflow:

/tdd
Set up mutation testing for this project using Stryker. 
Generate a mutation testing report and analyze which mutations 
survived our test suite. Focus on mutations in the core business logic.

Claude loads the tdd skill and analyzes your project structure. It checks for existing test files, understands the module boundaries, and identifies where mutation testing should run. The skill prompts you for configuration preferences and runs the mutation testing tool.

Interpreting Results

When mutation testing completes, you receive a survival rate—the percentage of mutations your tests caught versus total mutations. Aim for above 80% survival rate (meaning 80% of mutations were killed by your tests).

Review the surviving mutations:

Mutation testing results:
- src/utils/validators.js: 2 mutations survived
  - Line 14: changed email regex (test did not check invalid format)
  - Line 22: changed password length comparison (test used weak assertion)
- src/services/payment.js: 0 mutations survived (good coverage)

These surviving mutations reveal specific gaps. The email validation test likely only tested valid formats, not edge cases. The password length check probably used a weak assertion like >= 8 instead of testing boundary conditions.

Integrating with Claude Skills

The supermemory skill stores mutation testing results across sessions:

/supermemory
Store mutation testing baseline:
- Current survival rate: 78%
- Priority fixes needed in validators.js
- payment.js has excellent coverage
- Run mutation tests before each release

This creates institutional knowledge your team can reference. Future Claude sessions know the mutation testing baseline and can prioritize fixes accordingly.

The pdf skill generates mutation testing reports for stakeholders:

/pdf
Generate a mutation testing summary report for Q1 2026.
Include: overall survival rate, trends over time,
and specific code areas needing attention.

Automating the Workflow

Add mutation testing to your CI pipeline. Create a script in package.json:

{
  "scripts": {
    "test:mutation": "stryker run",
    "prebuild": "npm run test:mutation"
  }
}

The prebuild hook ensures mutation tests pass before any deployment. Set your CI thresholds to fail builds below your target survival rate.

For teams adopting continuous improvement, track mutation survival rate over time. A dropping rate indicates test quality degradation and warrants investigation.

Practical Example

Consider a simple function in src/calculate.js:

export function calculateDiscount(price, isPremium) {
  if (isPremium) {
    return price * 0.9;
  }
  return price;
}

Your test might be:

test('premium gets 10% discount', () => {
  expect(calculateDiscount(100, true)).toBe(90);
});

Mutation testing changes * 0.9 to * 0.8. Your test fails—you caught the mutation. But changing === true to !isPremium makes the test fail incorrectly because it was written for that specific implementation, not the intended behavior.

The fix: write behavioral tests, not implementation tests:

test('premium customers receive discount', () => {
  const discounted = calculateDiscount(100, true);
  expect(discounted).toBeLessThan(100);
  expect(discounted).toBeGreaterThan(0);
});

Now mutations to the discount logic are caught while implementation details remain flexible.

Conclusion

Mutation testing transforms test quality from “lines covered” to “bugs actually caught.” Using Claude Code with the tdd skill creates a practical workflow: analyze code, run mutations, interpret results, and improve test assertions. The supermemory skill preserves this knowledge, and the pdf skill generates reports for team communication.

Start with a single module, establish your baseline survival rate, and iterate. Your test suite becomes genuinely reliable when it consistently catches artificial defects.

Built by theluckystrike — More at zovo.one