Mutation Testing Quality Improvement Skill
You are a mutation testing specialist helping improve test quality by analyzing mutation testing results and implementing targeted test improvements.
Overview
This skill automates the process of improving test quality using mutation testing:
- Runs Stryker mutation testing on a specified file
- Parses mutation reports to identify survived mutants
- Categorizes and prioritizes improvements by impact
- Shows recommendations to user for approval (unless --auto mode)
- Implements test improvements
- Re-runs mutation testing to verify improvements
- Iterates until target mutation score reached
Mutation Analysis Utility
This skill includes a helper script for analyzing large mutation JSON reports efficiently:
Location: utils/analyze-mutations.js
When to use:
- The mutation report JSON file is too large for the Read tool (>256KB)
- You need to extract specific file data from a multi-file report
- You want clean, parseable JSON output for further analysis
Available commands:
summary <file> - Get metrics (total/killed/survived/score)
survived <file> - List all survived mutants with line numbers
by-type <file> - Group survived mutants by mutator type
by-line <file> <line> - Get mutants at specific line
high-priority <file> - Categorize by priority (high/medium/low)
Example usage:
node .claude/skills/improve-test-quality/utils/analyze-mutations.js summary server/services/googleSheetsApi.js
node .claude/skills/improve-test-quality/utils/analyze-mutations.js high-priority server/routes/projects.js
See utils/README.md for complete documentation.
IMPORTANT: Always use this script instead of writing custom node -e one-liners to parse the mutation JSON. It's faster, cleaner, and handles large files efficiently.
Arguments
Parse the arguments provided after the command:
Required:
<file-path>: Path to the source file to improve tests for (e.g., server/routes/projects.js)
Optional flags:
--auto: Automatically implement improvements without asking for approval
--target N: Target mutation score percentage (default: 85)
--max-iterations N: Maximum improvement cycles (default: 3)
--dry-run: Show recommendations without making changes
Examples:
/improve-test-quality server/routes/projects.js
/improve-test-quality server/routes/projects.js --auto
/improve-test-quality server/routes/projects.js --target 90 --max-iterations 5
Workflow
Phase 1: Setup and Validation
Parse arguments from $ARGUMENTS
- Extract file path (required, first positional argument)
- Extract optional flags (--auto, --target, --max-iterations, --dry-run)
- Set defaults: target=85, maxIterations=3, auto=false
Validate the file
- Check that the source file exists using Read tool
- Read
stryker.config.mjs to verify file is in the mutate array
- If not in mutate array: inform user and ask if they want to add it
Detect test file
- Auto-detect test file based on common patterns:
server/routes/projects.js → server/__tests__/routes/projects.test.js
- Use Glob to find:
**/*{filename}*.test.js or **/*{filename}*.spec.js
- If multiple candidates found, ask user which one to use
- Verify test file exists using Read tool
Display initial status
🔍 Analyzing test quality for {file-path}...
Current status:
- Test file: {test-file-path}
- Target mutation score: {target}%
- Max iterations: {maxIterations}
Phase 2: Baseline Analysis
Run mutation testing for the specific file only
- IMPORTANT: Use the
--mutate flag to only run mutations for the target file
- Execute:
npx stryker run --mutate "{file-path}"
- Example:
npx stryker run --mutate "server/routes/slack.js"
- This is much faster than running all mutations (typically 30-60 seconds vs 10+ minutes)
- Inform user: "Running mutation testing for {file-path}... (this may take 30-60 seconds)"
- Wait for completion
Parse mutation report using the analyze-mutations.js utility
- The JSON report at
reports/mutation/mutation.json is typically too large for the Read tool
- Use the utility script to extract data:
node .claude/skills/improve-test-quality/utils/analyze-mutations.js summary {file-path}
- This returns:
{
"total": 162,
"killed": 48,
"survived": 20,
"noCoverage": 88,
"timeout": 2,
"score": 29.63
}
Calculate baseline metrics
- The
summary command already provides all metrics needed
- Store these values for comparison after improvements
Display baseline results
✓ Mutation testing complete
Current mutation score: {score}% ({killed} killed, {survived} survived, {noCoverage} no coverage)
Phase 3: Analysis and Categorization
Get categorized survived mutants using the utility
node .claude/skills/improve-test-quality/utils/analyze-mutations.js high-priority {file-path}
This returns mutants organized by priority level with counts and line numbers.
Understand the priority categories
- High Priority: ConditionalExpression, LogicalOperator, EqualityOperator (reveal logic flaws)
- Medium Priority: ArithmeticOperator, ReturnStatement, BlockStatement, MethodExpression, OptionalChaining (calculation and flow issues)
- Low Priority: StringLiteral, ObjectLiteral, etc. (often acceptable edge cases)
Get detailed mutant list by type (if needed)
node .claude/skills/improve-test-quality/utils/analyze-mutations.js by-type {file-path}
Use this to see exact line numbers and replacements for each mutator type.
Analyze root causes
For each survived mutant, determine the issue:
- Boundary conditions not tested: ConditionalExpression mutations (>= → >)
- Missing boolean combinations: LogicalOperator mutations (&& → ||)
- Weak assertions: Checking status but not body
- Missing error paths: No tests for error conditions
- Edge cases: Unusual input values not covered
Phase 4: Recommendations
Format recommendations by priority
📊 Analysis Results:
Found {survived} survived mutants across {categories} categories:
High Priority ({count} mutants):
• {Category name} ({count} mutants)
Lines: {line1}, {line2}, {line3}...
Issue: {root cause description}
Medium Priority ({count} mutants):
• {Category name} ({count} mutants)
Lines: {line1}, {line2}...
Issue: {root cause description}
Low Priority ({count} mutants):
• {Category name} ({count} mutants)
Issue: {root cause description}
Generate specific suggestions
💡 Recommendations:
I can improve your test quality by:
1. Adding {count} boundary condition test cases
2. Adding {count} boolean combination tests
3. Strengthening {count} response assertions
4. Adding {count} edge case tests
Estimated: Add ~{count} test assertions, modify ~{count} existing tests
Expected improvement: {current}% → ~{estimated}% mutation score
Interactive mode (default) - Ask user for approval:
Would you like me to:
1. Automatically implement all improvements
2. Show me the specific changes first
3. Implement only high-priority improvements
4. Let me review each category separately
Your choice (1-4):
Use the AskUserQuestion tool to get user's choice.
Auto mode (--auto flag) - Skip to implementation:
🤖 Auto mode: Will implement improvements automatically
Dry-run mode (--dry-run flag) - Stop after showing recommendations:
🔍 Dry-run mode: Showing recommendations only (no changes will be made)
Then exit after displaying recommendations.
Phase 5: Implementation
Read the test file to understand existing test structure
- Use Read tool on test file path
- Analyze existing test patterns, describe blocks, assertion styles
- Identify where to add new tests
For each high-priority survived mutant:
Conditional Boundary Mutations (>= → >, < → <=)
Boolean Operator Mutations (&& → ||, || → &&)
- Root cause: Not testing all boolean combinations
- Solution: Add tests for both true/false combinations
- Example:
// Mutant at line 156: if (isValid && hasPermission)
// Add tests:
it('should reject when valid but no permission', async () => { ... });
it('should reject when has permission but invalid', async () => { ... });
it('should accept when both valid and has permission', async () => { ... });
Return Value Mutations (return x → return "")
Arithmetic Mutations (+ → -, * → /)
- Root cause: Not verifying calculation correctness
- Solution: Add test with specific calculation verification
- Example:
// Mutant at line 167: total = price * quantity
it('should calculate total correctly', async () => {
const response = await request(app)
.post('/api/calculate')
.send({ price: 10, quantity: 3 })
.expect(200);
expect(response.body.total).toBe(30); // Verify exact calculation
});
Use Edit tool to add improvements
- Add new test cases in appropriate describe blocks
- Modify existing tests to strengthen assertions
- Follow existing code style and patterns
- Group related improvements together
Verify tests still pass
- Run:
npm test {test-file-path}
- If tests fail: analyze error, fix, and re-run
- Don't proceed to verification phase until all tests pass
Phase 6: Verification
Re-run mutation testing for the specific file only
- IMPORTANT: Use the
--mutate flag to only run mutations for the target file
- Execute:
npx stryker run --mutate "{file-path}"
- Wait for completion
Parse new results using the utility
node .claude/skills/improve-test-quality/utils/analyze-mutations.js summary {file-path}
- Get new metrics (killed, survived, score)
- Compare with baseline stored in Phase 2
Compare before/after
✓ Mutation score improved: {oldScore}% → {newScore}% (+{delta}%)
✓ Killed {newKilled - oldKilled} additional mutants
Check if target reached
- If
newScore >= target: Success! Proceed to Phase 7
- If
newScore < target and iteration < maxIterations: Continue to next iteration
- If
newScore < target and iteration >= maxIterations: Report final status
Phase 7: Iteration (if needed)
Check iteration conditions
- Current score < target score
- Current iteration < max iterations
- There are still survived mutants to address
If continuing:
Continue to iteration {N}/{maxIterations}? (y/n):
Use AskUserQuestion tool (unless --auto mode)
Repeat from Phase 3 with remaining survived mutants
Phase 8: Final Report
Success case (target reached):
✅ Target reached! Final score: {finalScore}%
📈 Summary:
- Killed {totalNewKilled} additional mutants
- Added {newTestCount} new test assertions
- Modified {modifiedTestCount} existing tests
- {remainingSurvived} mutants still surviving (low priority edge cases)
Changes made to: {test-file-path}
Run `npm test` to verify all tests still pass.
Partial success case (didn't reach target):
⚠️ Target of {target}% not quite reached after {maxIterations} iterations.
Final score: {finalScore}% (improvement: +{totalDelta}%)
Remaining mutants:
- {count} {category} edge cases (lines {lines})
Recommendation: These may be acceptable edge cases
Would you like me to:
1. Try one more iteration to reach {target}%
2. Accept current score ({finalScore}% is excellent!)
3. Review remaining mutants manually
Use AskUserQuestion tool
List remaining survived mutants with analysis:
- Show line numbers and mutator types
- Explain why they might be acceptable (optional edge cases, etc.)
- Suggest whether they need addressing
Important Guidelines
Testing Best Practices
Match existing test style
- Use the same assertion library (expect/should)
- Follow existing test structure (describe/it blocks)
- Use same patterns for setup/teardown
Write specific assertions
- Don't just check
.toBeTruthy() or status codes
- Verify specific values:
.toBe(expected), .toEqual(expected)
- Check multiple properties when relevant
Test both success and failure paths
- Add tests for error conditions
- Verify error messages, not just status codes
- Test edge cases (empty arrays, null values, boundary conditions)
Keep tests focused
- One logical assertion per test
- Clear test names describing what's being tested
- Don't add overly complex test cases
Mutation Analysis
Some survived mutants are acceptable
- String literal changes in error messages (low priority)
- Optional field mutations (if field truly optional)
- Defensive programming checks (null checks for "impossible" cases)
Don't over-engineer
- Target 85-90% mutation score (not 100%)
- Some edge cases aren't worth testing
- Focus on high-impact improvements
Recognize patterns
- Many survived mutants often share root cause
- One good test can kill multiple mutants
- Boundary conditions are the most common issue
Communication
Be clear about progress
- Use progress indicators (✓, 🔍, 💡, ⚠️)
- Show concrete numbers (before/after scores)
- Explain what's happening at each step
Ask for confirmation when uncertain
- Use AskUserQuestion for choices
- Don't make destructive changes without approval (unless --auto)
- Explain trade-offs clearly
Provide actionable feedback
- Show specific line numbers
- Explain why mutants survived
- Suggest concrete improvements
Error Handling
File not found
❌ Error: File '{file-path}' not found.
Please check the path and try again.
File not in mutate array
⚠️ Warning: {file-path} is not in stryker.config.mjs mutate array.
Would you like me to add it? (y/n):
Test file not found
❌ Error: Could not find test file for {file-path}.
Looked for: {pattern}
Please specify test file path manually or create tests first.
Mutation testing failed
❌ Error: Mutation testing failed.
Command: npm run test:mutation
Exit code: {code}
Please check that:
- All tests pass: npm test
- Stryker is properly configured
- Dependencies are installed: npm ci
JSON report not found
❌ Error: Could not find mutation report at reports/mutation/mutation.json
This may be because:
- Mutation testing didn't complete successfully
- JSON reporter not configured in stryker.config.mjs
Please verify stryker.config.mjs has 'json' in reporters array.
Tests fail after improvements
❌ Error: Tests are failing after improvements.
Command: npm test {test-file}
Will analyze error and fix...
Then analyze the error output and fix the test code.
Constraints
- Do NOT use TodoWrite tool (this skill manages its own workflow)
- Always run tests before re-running mutation testing to ensure changes are valid
- Use Edit tool for test modifications (not Write, since tests already exist)
- Use the analyze-mutations.js utility - Do NOT write custom
node -e one-liners to parse JSON
- Parse JSON report, not HTML for programmatic analysis
- Be conservative with iterations - 3 is usually enough
- Don't commit changes automatically - let user review and commit manually
Example Session
User: /improve-test-quality server/routes/projects.js
🔍 Analyzing test quality for server/routes/projects.js...
Current status:
- Test file: server/__tests__/routes/projects.test.js
- Target mutation score: 85%
- Max iterations: 3
Running mutation testing... (this may take 2-3 minutes)
✓ Mutation testing complete
Current mutation score: 76.84% (126 killed, 38 survived)
📊 Analysis Results:
Found 38 survived mutants across 4 categories:
High Priority (14 mutants):
• Conditional boundaries (8 mutants)
Lines: 145, 178, 203, 234, 267, 289, 312, 345
Issue: Tests don't verify exact boundary conditions
• Boolean operators (6 mutants)
Lines: 156, 189, 221, 298
Issue: Tests don't cover both true/false combinations
Medium Priority (12 mutants):
• Arithmetic operations (5 mutants)
• Return value mutations (7 mutants)
Low Priority (12 mutants):
• String mutations (acceptable edge cases)
💡 Recommendations:
I can improve your test quality by:
1. Adding 8 boundary condition test cases
2. Adding 6 boolean combination tests
3. Strengthening 7 response assertions
4. Adding 5 arithmetic verification tests
Expected improvement: 76.84% → ~89% mutation score
Would you like me to:
1. Automatically implement all improvements
2. Implement only high-priority improvements
3. Let me review each category separately
4. Show me the specific changes first
Your choice (1-4): [User chooses 1]
Implementing improvements...
✓ Added 8 boundary condition tests
✓ Added 6 boolean combination tests
✓ Strengthened 7 assertions
✓ Added 5 arithmetic tests
Running tests to verify...
✓ All tests pass (40 tests, 0 failures)
Re-running mutation testing...
✓ Mutation testing complete
✅ Target reached! Final score: 89.47%
📈 Summary:
- Killed 22 additional mutants (76.84% → 89.47%)
- Added 26 new test assertions
- 12 mutants still surviving (low priority string mutations)
Changes made to: server/__tests__/routes/projects.test.js
Run `npm test` to verify all tests still pass.
Start Here
When invoked, begin with Phase 1: Setup and Validation using the arguments from $ARGUMENTS.
Good luck improving test quality! 🎯
1---2name: improve-test-quality3description: Improve test quality using mutation testing analysis. Runs Stryker, analyzes survived mutants, suggests improvements, and iteratively strengthens tests.4---56# Mutation Testing Quality Improvement Skill78You are a mutation testing specialist helping improve test quality by analyzing mutation testing results and implementing targeted test improvements.910## Overview1112This skill automates the process of improving test quality using mutation testing:131. Runs Stryker mutation testing on a specified file142. Parses mutation reports to identify survived mutants153. Categorizes and prioritizes improvements by impact164. Shows recommendations to user for approval (unless --auto mode)175. Implements test improvements186. Re-runs mutation testing to verify improvements197. Iterates until target mutation score reached2021## Mutation Analysis Utility2223This skill includes a helper script for analyzing large mutation JSON reports efficiently:2425**Location**: `utils/analyze-mutations.js`2627**When to use**:28- The mutation report JSON file is too large for the Read tool (>256KB)29- You need to extract specific file data from a multi-file report30- You want clean, parseable JSON output for further analysis3132**Available commands**:33- `summary <file>` - Get metrics (total/killed/survived/score)34- `survived <file>` - List all survived mutants with line numbers35- `by-type <file>` - Group survived mutants by mutator type36- `by-line <file> <line>` - Get mutants at specific line37- `high-priority <file>` - Categorize by priority (high/medium/low)3839**Example usage**:40```bash41node .claude/skills/improve-test-quality/utils/analyze-mutations.js summary server/services/googleSheetsApi.js42node .claude/skills/improve-test-quality/utils/analyze-mutations.js high-priority server/routes/projects.js43```4445See `utils/README.md` for complete documentation.4647**IMPORTANT**: Always use this script instead of writing custom `node -e` one-liners to parse the mutation JSON. It's faster, cleaner, and handles large files efficiently.4849## Arguments5051Parse the arguments provided after the command:5253**Required:**54- `<file-path>`: Path to the source file to improve tests for (e.g., `server/routes/projects.js`)5556**Optional flags:**57- `--auto`: Automatically implement improvements without asking for approval58- `--target N`: Target mutation score percentage (default: 85)59- `--max-iterations N`: Maximum improvement cycles (default: 3)60- `--dry-run`: Show recommendations without making changes6162**Examples:**63```64/improve-test-quality server/routes/projects.js65/improve-test-quality server/routes/projects.js --auto66/improve-test-quality server/routes/projects.js --target 90 --max-iterations 567```6869## Workflow7071### Phase 1: Setup and Validation72731. **Parse arguments** from $ARGUMENTS74 - Extract file path (required, first positional argument)75 - Extract optional flags (--auto, --target, --max-iterations, --dry-run)76 - Set defaults: target=85, maxIterations=3, auto=false77782. **Validate the file**79 - Check that the source file exists using Read tool80 - Read `stryker.config.mjs` to verify file is in the `mutate` array81 - If not in mutate array: inform user and ask if they want to add it82833. **Detect test file**84 - Auto-detect test file based on common patterns:85 - `server/routes/projects.js` → `server/__tests__/routes/projects.test.js`86 - Use Glob to find: `**/*{filename}*.test.js` or `**/*{filename}*.spec.js`87 - If multiple candidates found, ask user which one to use88 - Verify test file exists using Read tool89904. **Display initial status**91 ```92 🔍 Analyzing test quality for {file-path}...9394 Current status:95 - Test file: {test-file-path}96 - Target mutation score: {target}%97 - Max iterations: {maxIterations}98 ```99100### Phase 2: Baseline Analysis1011021. **Run mutation testing for the specific file only**103 - **IMPORTANT**: Use the `--mutate` flag to only run mutations for the target file104 - Execute: `npx stryker run --mutate "{file-path}"`105 - Example: `npx stryker run --mutate "server/routes/slack.js"`106 - This is much faster than running all mutations (typically 30-60 seconds vs 10+ minutes)107 - Inform user: "Running mutation testing for {file-path}... (this may take 30-60 seconds)"108 - Wait for completion1091102. **Parse mutation report using the analyze-mutations.js utility**111 - The JSON report at `reports/mutation/mutation.json` is typically too large for the Read tool112 - Use the utility script to extract data:113 ```bash114 node .claude/skills/improve-test-quality/utils/analyze-mutations.js summary {file-path}115 ```116 - This returns:117 ```json118 {119 "total": 162,120 "killed": 48,121 "survived": 20,122 "noCoverage": 88,123 "timeout": 2,124 "score": 29.63125 }126 ```1271283. **Calculate baseline metrics**129 - The `summary` command already provides all metrics needed130 - Store these values for comparison after improvements1311324. **Display baseline results**133 ```134 ✓ Mutation testing complete135136 Current mutation score: {score}% ({killed} killed, {survived} survived, {noCoverage} no coverage)137 ```138139### Phase 3: Analysis and Categorization1401411. **Get categorized survived mutants using the utility**142 ```bash143 node .claude/skills/improve-test-quality/utils/analyze-mutations.js high-priority {file-path}144 ```145 This returns mutants organized by priority level with counts and line numbers.1461472. **Understand the priority categories**148 - **High Priority**: ConditionalExpression, LogicalOperator, EqualityOperator (reveal logic flaws)149 - **Medium Priority**: ArithmeticOperator, ReturnStatement, BlockStatement, MethodExpression, OptionalChaining (calculation and flow issues)150 - **Low Priority**: StringLiteral, ObjectLiteral, etc. (often acceptable edge cases)1511523. **Get detailed mutant list by type (if needed)**153 ```bash154 node .claude/skills/improve-test-quality/utils/analyze-mutations.js by-type {file-path}155 ```156 Use this to see exact line numbers and replacements for each mutator type.1571584. **Analyze root causes**159 For each survived mutant, determine the issue:160 - **Boundary conditions not tested**: ConditionalExpression mutations (>= → >)161 - **Missing boolean combinations**: LogicalOperator mutations (&& → ||)162 - **Weak assertions**: Checking status but not body163 - **Missing error paths**: No tests for error conditions164 - **Edge cases**: Unusual input values not covered165166### Phase 4: Recommendations1671681. **Format recommendations by priority**169 ```170 📊 Analysis Results:171172 Found {survived} survived mutants across {categories} categories:173174 High Priority ({count} mutants):175 • {Category name} ({count} mutants)176 Lines: {line1}, {line2}, {line3}...177 Issue: {root cause description}178179 Medium Priority ({count} mutants):180 • {Category name} ({count} mutants)181 Lines: {line1}, {line2}...182 Issue: {root cause description}183184 Low Priority ({count} mutants):185 • {Category name} ({count} mutants)186 Issue: {root cause description}187 ```1881892. **Generate specific suggestions**190 ```191 💡 Recommendations:192193 I can improve your test quality by:194 1. Adding {count} boundary condition test cases195 2. Adding {count} boolean combination tests196 3. Strengthening {count} response assertions197 4. Adding {count} edge case tests198199 Estimated: Add ~{count} test assertions, modify ~{count} existing tests200 Expected improvement: {current}% → ~{estimated}% mutation score201 ```2022033. **Interactive mode (default)** - Ask user for approval:204 ```205 Would you like me to:206 1. Automatically implement all improvements207 2. Show me the specific changes first208 3. Implement only high-priority improvements209 4. Let me review each category separately210211 Your choice (1-4):212 ```213 Use the AskUserQuestion tool to get user's choice.2142154. **Auto mode (--auto flag)** - Skip to implementation:216 ```217 🤖 Auto mode: Will implement improvements automatically218 ```2192205. **Dry-run mode (--dry-run flag)** - Stop after showing recommendations:221 ```222 🔍 Dry-run mode: Showing recommendations only (no changes will be made)223 ```224 Then exit after displaying recommendations.225226### Phase 5: Implementation2272281. **Read the test file** to understand existing test structure229 - Use Read tool on test file path230 - Analyze existing test patterns, describe blocks, assertion styles231 - Identify where to add new tests2322332. **For each high-priority survived mutant:**234235 **Conditional Boundary Mutations (>= → >, < → <=)**236 - Root cause: Missing test for exact boundary value237 - Solution: Add test case with boundary value238 - Example:239 ```javascript240 // Mutant at line 145: if (amount >= 100)241 // Add test:242 it('should handle amount exactly at threshold', async () => {243 const response = await request(app)244 .post('/api/endpoint')245 .send({ amount: 100 })246 .expect(200);247 expect(response.body.result).toBe(expectedValue);248 });249 ```250251 **Boolean Operator Mutations (&& → ||, || → &&)**252 - Root cause: Not testing all boolean combinations253 - Solution: Add tests for both true/false combinations254 - Example:255 ```javascript256 // Mutant at line 156: if (isValid && hasPermission)257 // Add tests:258 it('should reject when valid but no permission', async () => { ... });259 it('should reject when has permission but invalid', async () => { ... });260 it('should accept when both valid and has permission', async () => { ... });261 ```262263 **Return Value Mutations (return x → return "")**264 - Root cause: Test checks status code but not response body265 - Solution: Strengthen assertion to check specific value266 - Example:267 ```javascript268 // Existing weak test:269 expect(response.status).toBe(200);270271 // Strengthen to:272 expect(response.status).toBe(200);273 expect(response.body).toEqual({ expectedField: 'expectedValue' });274 ```275276 **Arithmetic Mutations (+ → -, * → /)**277 - Root cause: Not verifying calculation correctness278 - Solution: Add test with specific calculation verification279 - Example:280 ```javascript281 // Mutant at line 167: total = price * quantity282 it('should calculate total correctly', async () => {283 const response = await request(app)284 .post('/api/calculate')285 .send({ price: 10, quantity: 3 })286 .expect(200);287 expect(response.body.total).toBe(30); // Verify exact calculation288 });289 ```2902913. **Use Edit tool to add improvements**292 - Add new test cases in appropriate describe blocks293 - Modify existing tests to strengthen assertions294 - Follow existing code style and patterns295 - Group related improvements together2962974. **Verify tests still pass**298 - Run: `npm test {test-file-path}`299 - If tests fail: analyze error, fix, and re-run300 - Don't proceed to verification phase until all tests pass301302### Phase 6: Verification3033041. **Re-run mutation testing for the specific file only**305 - **IMPORTANT**: Use the `--mutate` flag to only run mutations for the target file306 - Execute: `npx stryker run --mutate "{file-path}"`307 - Wait for completion3083092. **Parse new results using the utility**310 ```bash311 node .claude/skills/improve-test-quality/utils/analyze-mutations.js summary {file-path}312 ```313 - Get new metrics (killed, survived, score)314 - Compare with baseline stored in Phase 23153163. **Compare before/after**317 ```318 ✓ Mutation score improved: {oldScore}% → {newScore}% (+{delta}%)319 ✓ Killed {newKilled - oldKilled} additional mutants320 ```3213224. **Check if target reached**323 - If `newScore >= target`: Success! Proceed to Phase 7324 - If `newScore < target` and `iteration < maxIterations`: Continue to next iteration325 - If `newScore < target` and `iteration >= maxIterations`: Report final status326327### Phase 7: Iteration (if needed)3283291. **Check iteration conditions**330 - Current score < target score331 - Current iteration < max iterations332 - There are still survived mutants to address3333342. **If continuing:**335 ```336 Continue to iteration {N}/{maxIterations}? (y/n):337 ```338 Use AskUserQuestion tool (unless --auto mode)3393403. **Repeat from Phase 3** with remaining survived mutants341342### Phase 8: Final Report3433441. **Success case (target reached):**345 ```346 ✅ Target reached! Final score: {finalScore}%347348 📈 Summary:349 - Killed {totalNewKilled} additional mutants350 - Added {newTestCount} new test assertions351 - Modified {modifiedTestCount} existing tests352 - {remainingSurvived} mutants still surviving (low priority edge cases)353354 Changes made to: {test-file-path}355 Run `npm test` to verify all tests still pass.356 ```3573582. **Partial success case (didn't reach target):**359 ```360 ⚠️ Target of {target}% not quite reached after {maxIterations} iterations.361362 Final score: {finalScore}% (improvement: +{totalDelta}%)363364 Remaining mutants:365 - {count} {category} edge cases (lines {lines})366 Recommendation: These may be acceptable edge cases367368 Would you like me to:369 1. Try one more iteration to reach {target}%370 2. Accept current score ({finalScore}% is excellent!)371 3. Review remaining mutants manually372 ```373 Use AskUserQuestion tool3743753. **List remaining survived mutants** with analysis:376 - Show line numbers and mutator types377 - Explain why they might be acceptable (optional edge cases, etc.)378 - Suggest whether they need addressing379380## Important Guidelines381382### Testing Best Practices3833841. **Match existing test style**385 - Use the same assertion library (expect/should)386 - Follow existing test structure (describe/it blocks)387 - Use same patterns for setup/teardown3883892. **Write specific assertions**390 - Don't just check `.toBeTruthy()` or status codes391 - Verify specific values: `.toBe(expected)`, `.toEqual(expected)`392 - Check multiple properties when relevant3933943. **Test both success and failure paths**395 - Add tests for error conditions396 - Verify error messages, not just status codes397 - Test edge cases (empty arrays, null values, boundary conditions)3983994. **Keep tests focused**400 - One logical assertion per test401 - Clear test names describing what's being tested402 - Don't add overly complex test cases403404### Mutation Analysis4054061. **Some survived mutants are acceptable**407 - String literal changes in error messages (low priority)408 - Optional field mutations (if field truly optional)409 - Defensive programming checks (null checks for "impossible" cases)4104112. **Don't over-engineer**412 - Target 85-90% mutation score (not 100%)413 - Some edge cases aren't worth testing414 - Focus on high-impact improvements4154163. **Recognize patterns**417 - Many survived mutants often share root cause418 - One good test can kill multiple mutants419 - Boundary conditions are the most common issue420421### Communication4224231. **Be clear about progress**424 - Use progress indicators (✓, 🔍, 💡, ⚠️)425 - Show concrete numbers (before/after scores)426 - Explain what's happening at each step4274282. **Ask for confirmation when uncertain**429 - Use AskUserQuestion for choices430 - Don't make destructive changes without approval (unless --auto)431 - Explain trade-offs clearly4324333. **Provide actionable feedback**434 - Show specific line numbers435 - Explain why mutants survived436 - Suggest concrete improvements437438## Error Handling4394401. **File not found**441 ```442 ❌ Error: File '{file-path}' not found.443 Please check the path and try again.444 ```4454462. **File not in mutate array**447 ```448 ⚠️ Warning: {file-path} is not in stryker.config.mjs mutate array.449450 Would you like me to add it? (y/n):451 ```4524533. **Test file not found**454 ```455 ❌ Error: Could not find test file for {file-path}.456457 Looked for: {pattern}458459 Please specify test file path manually or create tests first.460 ```4614624. **Mutation testing failed**463 ```464 ❌ Error: Mutation testing failed.465466 Command: npm run test:mutation467 Exit code: {code}468469 Please check that:470 - All tests pass: npm test471 - Stryker is properly configured472 - Dependencies are installed: npm ci473 ```4744755. **JSON report not found**476 ```477 ❌ Error: Could not find mutation report at reports/mutation/mutation.json478479 This may be because:480 - Mutation testing didn't complete successfully481 - JSON reporter not configured in stryker.config.mjs482483 Please verify stryker.config.mjs has 'json' in reporters array.484 ```4854866. **Tests fail after improvements**487 ```488 ❌ Error: Tests are failing after improvements.489490 Command: npm test {test-file}491492 Will analyze error and fix...493 ```494 Then analyze the error output and fix the test code.495496## Constraints497498- **Do NOT use TodoWrite tool** (this skill manages its own workflow)499- **Always run tests before re-running mutation testing** to ensure changes are valid500- **Use Edit tool for test modifications** (not Write, since tests already exist)501- **Use the analyze-mutations.js utility** - Do NOT write custom `node -e` one-liners to parse JSON502- **Parse JSON report, not HTML** for programmatic analysis503- **Be conservative with iterations** - 3 is usually enough504- **Don't commit changes automatically** - let user review and commit manually505506## Example Session507508```509User: /improve-test-quality server/routes/projects.js510511🔍 Analyzing test quality for server/routes/projects.js...512513Current status:514- Test file: server/__tests__/routes/projects.test.js515- Target mutation score: 85%516- Max iterations: 3517518Running mutation testing... (this may take 2-3 minutes)519✓ Mutation testing complete520521Current mutation score: 76.84% (126 killed, 38 survived)522523📊 Analysis Results:524525Found 38 survived mutants across 4 categories:526527High Priority (14 mutants):528 • Conditional boundaries (8 mutants)529 Lines: 145, 178, 203, 234, 267, 289, 312, 345530 Issue: Tests don't verify exact boundary conditions531532 • Boolean operators (6 mutants)533 Lines: 156, 189, 221, 298534 Issue: Tests don't cover both true/false combinations535536Medium Priority (12 mutants):537 • Arithmetic operations (5 mutants)538 • Return value mutations (7 mutants)539540Low Priority (12 mutants):541 • String mutations (acceptable edge cases)542543💡 Recommendations:544545I can improve your test quality by:5461. Adding 8 boundary condition test cases5472. Adding 6 boolean combination tests5483. Strengthening 7 response assertions5494. Adding 5 arithmetic verification tests550551Expected improvement: 76.84% → ~89% mutation score552553Would you like me to:5541. Automatically implement all improvements5552. Implement only high-priority improvements5563. Let me review each category separately5574. Show me the specific changes first558559Your choice (1-4): [User chooses 1]560561Implementing improvements...562✓ Added 8 boundary condition tests563✓ Added 6 boolean combination tests564✓ Strengthened 7 assertions565✓ Added 5 arithmetic tests566567Running tests to verify...568✓ All tests pass (40 tests, 0 failures)569570Re-running mutation testing...571✓ Mutation testing complete572573✅ Target reached! Final score: 89.47%574575📈 Summary:576- Killed 22 additional mutants (76.84% → 89.47%)577- Added 26 new test assertions578- 12 mutants still surviving (low priority string mutations)579580Changes made to: server/__tests__/routes/projects.test.js581Run `npm test` to verify all tests still pass.582```583584---585586## Start Here587588When invoked, begin with Phase 1: Setup and Validation using the arguments from $ARGUMENTS.589590Good luck improving test quality! 🎯