
Mutation Testing
- 96 installs
- 433 repo stars
- Updated August 4, 2026
- proffesor-for-testing/agentic-qe
mutation-testing is a Claude Code skill for testing & qa.
About
mutation-testing is a Claude Code skill for testing & qa. It helps solo builders move faster with AI-assisted development.
- mutation-testing
- Testing & QA
- AI-coding skill
Mutation Testing by the numbers
- 96 all-time installs (skills.sh)
- +3 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #1,015 of 2,153 Testing & QA skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/proffesor-for-testing/agentic-qe --skill mutation-testingAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 96 |
|---|---|
| repo stars | ★ 433 |
| Last updated | August 4, 2026 |
| Repository | proffesor-for-testing/agentic-qe ↗ |
How do I helps with testing & qa tasks.?
Helps with testing & qa tasks.
Who is it for?
Best when you're working on testing & qa and need structured help with mutation testing.
Skip if: Teams with no testing & qa needs, or anyone wanting a generic chat assistant without this specific workflow.
When should I use this skill?
When you need to helps with testing & qa tasks., or when mutation-testing is a claude code skill for testing & qa.
What you get
Structured output aligned to mutation-testing: mutation-testing, Testing & QA.
Files
Mutation Testing
<default_to_action> When validating test quality or improving test effectiveness: 1. MUTATE code (change + to -, >= to >, remove statements) 2. RUN tests against each mutant 3. VERIFY tests catch mutations (kill mutants) 4. IDENTIFY surviving mutants (tests need improvement) 5. STRENGTHEN tests to kill surviving mutants
Quick Mutation Metrics:
- Mutation Score = Killed / (Killed + Survived)
- Target: > 80% mutation score
- Surviving mutants = weak tests
Critical Success Factors:
- High coverage ≠ good tests (100% coverage, 0% assertions)
- Mutation testing proves tests actually catch bugs
- Focus on critical code paths first
</default_to_action>
Quick Reference Card
When to Use
- Evaluating test suite quality
- Finding gaps in test assertions
- Proving tests catch bugs
- Before critical releases
Mutation Score Interpretation
| Score | Interpretation |
|---|---|
| 90%+ | Excellent test quality |
| 80-90% | Good, minor improvements |
| 60-80% | Needs attention |
| < 60% | Significant gaps |
Common Mutation Operators
| Category | Original | Mutant |
|---|---|---|
| Arithmetic | a + b | a - b |
| Relational | x >= 18 | x > 18 |
| Logical | a && b | `a \ |
| Conditional | if (x) | if (true) |
| Statement | return x | (removed) |
---
How Mutation Testing Works
// Original code
function isAdult(age) {
return age >= 18; // ← Mutant: change >= to >
}
// Strong test (catches mutation)
test('18 is adult', () => {
expect(isAdult(18)).toBe(true); // Kills mutant!
});
// Weak test (mutation survives)
test('19 is adult', () => {
expect(isAdult(19)).toBe(true); // Doesn't catch >= vs >
});
// Surviving mutant → Test needs boundary value---
Using Stryker
# Install
npm install --save-dev @stryker-mutator/core @stryker-mutator/jest-runner
# Initialize
npx stryker initConfiguration:
{
"packageManager": "npm",
"reporters": ["html", "clear-text", "progress"],
"testRunner": "jest",
"coverageAnalysis": "perTest",
"mutate": [
"src/**/*.ts",
"!src/**/*.spec.ts"
],
"thresholds": {
"high": 90,
"low": 70,
"break": 60
}
}Run:
npx stryker runOutput:
Mutation Score: 87.3%
Killed: 124
Survived: 18
No Coverage: 3
Timeout: 1---
Fixing Surviving Mutants
// Surviving mutant: >= changed to >
function calculateDiscount(quantity) {
if (quantity >= 10) { // Mutant survives!
return 0.1;
}
return 0;
}
// Original weak test
test('large order gets discount', () => {
expect(calculateDiscount(15)).toBe(0.1); // Doesn't test boundary
});
// Fixed: Add boundary test
test('exactly 10 gets discount', () => {
expect(calculateDiscount(10)).toBe(0.1); // Kills mutant!
});
test('9 does not get discount', () => {
expect(calculateDiscount(9)).toBe(0); // Tests below boundary
});---
Agent-Driven Mutation Testing
// Analyze mutation score and generate fixes
await Task("Mutation Analysis", {
targetFile: 'src/payment.ts',
generateMissingTests: true,
minScore: 80
}, "qe-test-generator");
// Returns:
// {
// mutationScore: 0.65,
// survivedMutations: [
// { line: 45, operator: '>=', mutant: '>', killedBy: null }
// ],
// generatedTests: [
// 'test for boundary at line 45'
// ]
// }
// Coverage + mutation correlation
await Task("Coverage Quality Analysis", {
coverageData: coverageReport,
mutationData: mutationReport,
identifyWeakCoverage: true
}, "qe-coverage-analyzer");---
Agent Coordination Hints
Memory Namespace
aqe/mutation-testing/
├── mutation-results/* - Stryker reports
├── surviving/* - Surviving mutants
├── generated-tests/* - Tests to kill mutants
└── trends/* - Mutation score over timeFleet Coordination
const mutationFleet = await FleetManager.coordinate({
strategy: 'mutation-testing',
agents: [
'qe-test-generator', // Generate tests for survivors
'qe-coverage-analyzer', // Coverage correlation
'qe-quality-analyzer' // Quality assessment
],
topology: 'sequential'
});---
Related Skills
- tdd-london-chicago - Write effective tests first
- test-design-techniques - Boundary value analysis
- quality-metrics - Measure test effectiveness
---
Remember
High code coverage ≠ good tests. 100% coverage but weak assertions = useless. Mutation testing proves tests actually catch bugs.
Focus on critical paths first. Don't mutation test everything - prioritize payment, authentication, data integrity code.
With Agents: Agents run mutation analysis, identify surviving mutants, and generate missing test cases to kill them. Automated improvement of test quality.
Run History
After each mutation test run, append results to run-history.json in this skill directory:
node -e "
const fs = require('fs');
const h = JSON.parse(fs.readFileSync('.claude/skills/mutation-testing/run-history.json'));
h.runs.push({date: new Date().toISOString().split('T')[0], mutation_score_pct: SCORE, killed: KILLED, survived: SURVIVED});
fs.writeFileSync('.claude/skills/mutation-testing/run-history.json', JSON.stringify(h, null, 2));
"Read run-history.json before each run to track score improvements over time.
Skill Composition
- Before mutation testing → Run
/qe-test-generationto ensure tests exist - After mutation results → Use
/qe-coverage-analysisto prioritize improvement areas - Quality gate → Feed results into
/qe-quality-assessmentfor ship/no-ship decision
Gotchas
- Stryker requires
--testRunner jestexplicitly if both jest and vitest are installed - Mutating
>=to>in date comparisons rarely gets killed — add boundary tests - Running on files >500 LOC will timeout; use
--mutateto target specific functions --concurrencydefaults to CPU count which OOMs in containers — set to 2
{
"$schema": "./config-schema.json",
"_description": "Mutation Testing configuration. Auto-created on first run. Edit to customize.",
"mutator": "stryker",
"concurrency": 2,
"score_threshold": 80,
"options": {
"testRunner": null,
"mutateGlob": "src/**/*.{ts,js}",
"excludeGlob": "src/**/*.test.{ts,js}",
"timeoutMs": 60000
},
"_setupPrompt": "If testRunner is null, ask: 'Which test runner does this project use? (jest/vitest/mocha)'. Warn: concurrency defaults to 2 to avoid OOM in containers."
}
# =============================================================================
# Mutation Testing Skill Evaluation Test Suite v1.0.0
# Path: .claude/skills/mutation-testing/evals/mutation-testing.yaml
# =============================================================================
#
# This evaluation suite validates mutation testing skill behavior through:
# 1. Input/expected-output test cases for mutation operators
# 2. Multi-model consistency testing
# 3. Semantic validation of mutation analysis quality
# 4. AQE MCP integration for shared learning
#
# Schema: .claude/skills/.validation/schemas/skill-eval.schema.json
# =============================================================================
skill: mutation-testing
version: 1.0.0
description: >
Comprehensive evaluation test suite for the mutation-testing skill.
Tests mutation score calculation, operator detection, surviving mutant
analysis, and test improvement recommendations across multiple models
to ensure consistent, high-quality mutation analysis output.
# =============================================================================
# Multi-Model Configuration
# =============================================================================
models_to_test:
- claude-sonnet-4-6 # Primary (high accuracy expected)
- claude-haiku-4-5 # Fast model (minimum quality floor)
# =============================================================================
# MCP Integration Configuration
# =============================================================================
mcp_integration:
enabled: true
namespace: skill-validation/mutation-testing
query_patterns: true
track_outcomes: true
store_patterns: true
share_learning: true
update_quality_gate: true
target_agents:
- qe-learning-coordinator
- qe-queen-coordinator
- qe-mutation-tester
# =============================================================================
# ReasoningBank Learning Configuration
# =============================================================================
learning:
store_success_patterns: true
store_failure_patterns: true
pattern_ttl_days: 90
min_confidence_to_store: 0.7
cross_model_comparison: true
# =============================================================================
# Result Format Configuration
# =============================================================================
result_format:
json_output: true
markdown_report: true
include_raw_output: false
include_timing: true
include_token_usage: true
# =============================================================================
# Environment Setup
# =============================================================================
setup:
required_tools:
- jq
environment_variables:
MUTATION_TIMEOUT_MS: "30000"
fixtures:
- name: simple_arithmetic_code
content: |
function calculateTotal(price, quantity) {
return price * quantity;
}
- name: conditional_code
content: |
function isAdult(age) {
return age >= 18;
}
- name: complex_code
content: |
function processOrder(order) {
if (order.quantity <= 0) {
throw new Error('Invalid quantity');
}
let discount = 0;
if (order.quantity >= 10 && order.isPremium) {
discount = 0.1;
}
return order.price * order.quantity * (1 - discount);
}
# =============================================================================
# Test Cases
# =============================================================================
test_cases:
# -------------------------------------------------------------------------
# Basic Functionality Tests
# -------------------------------------------------------------------------
- id: tc001_basic_mutation_analysis
description: "Skill analyzes simple code and identifies potential mutations"
category: basic
priority: critical
input:
code: |
function add(a, b) {
return a + b;
}
context:
language: javascript
prompt: |
Analyze this code for mutation testing. Identify what mutations
could be applied and what tests would be needed to kill them.
expected_output:
must_contain:
- "mutation"
- "arithmetic"
- "+"
must_not_contain:
- "unable to analyze"
- "error"
finding_count:
min: 1
max: 10
validation:
schema_check: true
keyword_match_threshold: 0.8
reasoning_quality_min: 0.7
- id: tc002_mutation_score_calculation
description: "Skill correctly calculates mutation score from kill/survive data"
category: basic
priority: critical
input:
prompt: |
Given these mutation testing results:
- Total mutants: 100
- Killed: 85
- Survived: 12
- Timeout: 2
- No Coverage: 1
Calculate the mutation score and assess the test suite quality.
expected_output:
must_contain:
- "85"
- "mutation score"
- "quality"
must_match_regex:
- "8[0-9](\\.\\d+)?%" # Score around 85%
validation:
schema_check: true
keyword_match_threshold: 0.9
# -------------------------------------------------------------------------
# Arithmetic Operator Tests (AOR)
# -------------------------------------------------------------------------
- id: tc003_arithmetic_operator_mutation
description: "Skill identifies arithmetic operator mutations (+, -, *, /)"
category: operators
priority: high
input:
code: |
function calculateTotal(price, quantity, tax) {
const subtotal = price * quantity;
const taxAmount = subtotal * tax;
return subtotal + taxAmount;
}
context:
language: javascript
prompt: |
Perform mutation analysis focusing on arithmetic operators.
Identify all AOR (Arithmetic Operator Replacement) mutations.
expected_output:
must_contain:
- "arithmetic"
- "*"
- "+"
- "mutant"
must_not_contain:
- "no mutations"
validation:
schema_check: true
keyword_match_threshold: 0.8
# -------------------------------------------------------------------------
# Relational Operator Tests (ROR)
# -------------------------------------------------------------------------
- id: tc004_relational_operator_mutation
description: "Skill identifies relational operator mutations (>, <, >=, <=, ==, !=)"
category: operators
priority: high
input:
code: |
function isEligible(age, income) {
if (age >= 18 && income > 30000) {
return true;
}
if (age < 65 && income <= 100000) {
return true;
}
return false;
}
context:
language: javascript
prompt: |
Analyze this code for relational operator mutations (ROR).
Identify boundary conditions that need testing.
expected_output:
must_contain:
- "relational"
- ">="
- "boundary"
- "18"
must_not_contain:
- "unable"
validation:
schema_check: true
keyword_match_threshold: 0.8
reasoning_quality_min: 0.7
- id: tc005_boundary_mutation_detection
description: "Skill detects boundary value mutations (>= to >, etc.)"
category: operators
priority: critical
input:
code: |
function getDiscount(quantity) {
if (quantity >= 10) {
return 0.1; // 10% discount
}
return 0;
}
context:
language: javascript
prompt: |
This code has a boundary condition at quantity=10.
What mutation would test if the boundary is correctly tested?
What test case would kill that mutant?
expected_output:
must_contain:
- "10"
- "boundary"
- ">="
- ">"
must_not_contain:
- "no boundary"
validation:
schema_check: true
reasoning_quality_min: 0.8
# -------------------------------------------------------------------------
# Logical Operator Tests (LCR/LOD)
# -------------------------------------------------------------------------
- id: tc006_logical_operator_mutation
description: "Skill identifies logical operator mutations (&&, ||, !)"
category: operators
priority: high
input:
code: |
function canAccess(user) {
return user.isActive && (user.role === 'admin' || user.hasPermission);
}
context:
language: javascript
prompt: |
Analyze this code for logical connector replacements (LCR).
What happens if && is changed to || or vice versa?
expected_output:
must_contain:
- "logical"
- "&&"
- "||"
must_not_contain:
- "no logical"
validation:
schema_check: true
keyword_match_threshold: 0.8
# -------------------------------------------------------------------------
# Conditional Operator Tests (COR)
# -------------------------------------------------------------------------
- id: tc007_conditional_mutation
description: "Skill identifies conditional/decision mutations"
category: operators
priority: high
input:
code: |
function processPayment(payment) {
if (payment.amount > 0) {
if (payment.verified) {
return 'approved';
}
return 'pending';
}
return 'rejected';
}
context:
language: javascript
prompt: |
Analyze conditional mutations for this payment processing code.
Consider mutations like replacing conditions with true/false.
expected_output:
must_contain:
- "conditional"
- "if"
- "true"
- "false"
validation:
schema_check: true
keyword_match_threshold: 0.7
# -------------------------------------------------------------------------
# Return Value Tests (RVR)
# -------------------------------------------------------------------------
- id: tc008_return_value_mutation
description: "Skill identifies return value mutations"
category: operators
priority: medium
input:
code: |
function getStatus(code) {
if (code === 200) return 'success';
if (code === 404) return 'not found';
if (code >= 500) return 'error';
return 'unknown';
}
context:
language: javascript
prompt: |
Analyze return value mutations for this status code handler.
What mutations could be applied to the return statements?
expected_output:
must_contain:
- "return"
- "mutation"
- "success"
- "error"
validation:
schema_check: true
keyword_match_threshold: 0.7
# -------------------------------------------------------------------------
# Surviving Mutant Analysis Tests
# -------------------------------------------------------------------------
- id: tc009_surviving_mutant_analysis
description: "Skill analyzes surviving mutants and suggests test improvements"
category: analysis
priority: critical
input:
prompt: |
The following mutant survived:
- File: src/validator.ts
- Line: 45
- Original: if (age >= 18)
- Mutated: if (age > 18)
- Tests that cover this line: ['should validate adult', 'should validate minor']
Why did this mutant survive and what test would kill it?
expected_output:
must_contain:
- "boundary"
- "18"
- "test"
- "exactly"
must_not_contain:
- "cannot determine"
validation:
schema_check: true
reasoning_quality_min: 0.8
- id: tc010_weak_test_identification
description: "Skill identifies weak tests based on surviving mutants"
category: analysis
priority: high
input:
prompt: |
Mutation testing results for auth.test.js:
- 50 mutants generated in auth.js
- 35 killed by auth.test.js
- 15 survived
Surviving mutant operators:
- 8 relational (ROR)
- 5 boundary (BOR)
- 2 logical (LCR)
Analyze what makes auth.test.js weak and how to improve it.
expected_output:
must_contain:
- "weak"
- "boundary"
- "relational"
- "improve"
recommendation_count:
min: 1
validation:
schema_check: true
reasoning_quality_min: 0.7
# -------------------------------------------------------------------------
# Edge Cases
# -------------------------------------------------------------------------
- id: tc011_empty_code_handling
description: "Skill handles empty or minimal code gracefully"
category: edge_cases
priority: medium
input:
code: |
// Empty function
function noop() {}
context:
language: javascript
prompt: Analyze this code for mutation testing.
expected_output:
must_contain:
- "no mutation"
must_not_contain:
- "error"
- "crash"
validation:
schema_check: true
allow_partial: true
- id: tc012_complex_nested_conditions
description: "Skill handles complex nested conditions"
category: edge_cases
priority: medium
input:
code: |
function complexValidation(data) {
if (data && data.type === 'A') {
if (data.value > 0 && data.value <= 100) {
if (data.status === 'active' || data.override) {
return data.priority >= 1 && data.priority <= 5;
}
}
}
return false;
}
context:
language: javascript
prompt: |
Analyze all possible mutations in this complex nested validation.
Prioritize by impact.
expected_output:
must_contain:
- "nested"
- "condition"
- "mutation"
finding_count:
min: 5
validation:
schema_check: true
keyword_match_threshold: 0.7
# -------------------------------------------------------------------------
# Multi-Language Support
# -------------------------------------------------------------------------
- id: tc013_python_mutation_analysis
description: "Skill correctly analyzes Python code mutations"
category: language_support
priority: medium
input:
code: |
def calculate_price(base_price, discount_percent, tax_rate):
discount = base_price * (discount_percent / 100)
subtotal = base_price - discount
tax = subtotal * tax_rate
return subtotal + tax
context:
language: python
prompt: Analyze this Python code for mutation testing.
expected_output:
must_contain:
- "mutation"
- "arithmetic"
- "python"
validation:
schema_check: true
- id: tc014_typescript_mutation_analysis
description: "Skill correctly analyzes TypeScript code mutations"
category: language_support
priority: medium
input:
code: |
interface Order {
quantity: number;
price: number;
isPremium: boolean;
}
function calculateDiscount(order: Order): number {
if (order.quantity >= 10 && order.isPremium) {
return order.price * 0.15;
}
if (order.quantity >= 5) {
return order.price * 0.05;
}
return 0;
}
context:
language: typescript
prompt: Analyze this TypeScript code for mutation testing.
expected_output:
must_contain:
- "mutation"
- "typescript"
- "boundary"
validation:
schema_check: true
# -------------------------------------------------------------------------
# Integration with Coverage
# -------------------------------------------------------------------------
- id: tc015_coverage_mutation_correlation
description: "Skill correlates coverage with mutation score"
category: integration
priority: high
input:
prompt: |
Coverage report shows:
- Line coverage: 95%
- Branch coverage: 88%
Mutation testing shows:
- Mutation score: 65%
Analyze the gap between coverage and mutation score.
Why can high coverage coexist with low mutation score?
expected_output:
must_contain:
- "coverage"
- "mutation"
- "assertion"
- "quality"
must_not_contain:
- "coverage equals"
validation:
schema_check: true
reasoning_quality_min: 0.8
grading_rubric:
completeness: 0.4
accuracy: 0.4
actionability: 0.2
# =============================================================================
# Success Criteria
# =============================================================================
success_criteria:
# Minimum 90% of tests must pass
pass_rate: 0.9
# All critical tests must pass
critical_pass_rate: 1.0
# Minimum reasoning quality
avg_reasoning_quality: 0.7
# Maximum 5 minutes for full suite
max_execution_time_ms: 300000
# Maximum 15% variance between models
cross_model_variance: 0.15
# =============================================================================
# Metadata
# =============================================================================
metadata:
author: "@agentic-qe"
created: "2026-02-02"
last_updated: "2026-02-02"
coverage_target: >
Comprehensive mutation operator coverage (AOR, ROR, LCR, COR, RVR),
surviving mutant analysis, weak test identification, multi-language
support, and coverage correlation analysis.
related_skills:
- test-design-techniques
- coverage-analysis
- tdd-london-chicago
Mutation Operators Reference
Arithmetic Operators
| Original | Mutant | What It Tests |
|---|---|---|
a + b | a - b | Addition logic |
a * b | a / b | Multiplication logic |
a % b | a * b | Modulo logic |
Conditional Operators
| Original | Mutant | What It Tests |
|---|---|---|
a > b | a >= b | Off-by-one in boundaries |
a >= b | a > b | Boundary inclusion |
a === b | a !== b | Equality checks |
a && b | `a \ | \ |
Statement Mutations
| Original | Mutant | What It Tests |
|---|---|---|
return x | return !x | Return value negation |
if (cond) | if (true) | Condition relevance |
if (cond) | if (false) | Dead code detection |
statement | _(removed)_ | Statement necessity |
Common Surviving Mutants and Fixes
`>=` to `>` survives: Add boundary test with exact boundary value `&&` to `||` survives: Add test where only one condition is true Removed `return` survives: Function's return value isn't being checked `+1` to `-1` survives: Increment/decrement logic untested
Stryker Configuration Tips
--testRunner jest— explicit when multiple runners installed--concurrency 2— prevents OOM in containers--mutate 'src/**/*.ts,!src/**/*.d.ts'— skip type definitions--timeoutMS 60000— increase for slow test suites--thresholds.high 80 --thresholds.low 60— score quality bands
{
"_description": "Mutation testing run history. Append after each run. Claude reads this to track mutation score trends.",
"_format": "Each entry: {date, scope, mutation_score_pct, killed, survived, timeout, no_coverage, improvement_areas}",
"_instructions": "After running mutation testing, append results here. Track score improvements over time. Flag if score drops below threshold.",
"runs": []
}
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://agentic-qe.dev/schemas/mutation-testing-output.json",
"title": "Mutation Testing Skill Output Schema",
"description": "Schema for mutation testing skill output validation. Validates mutation scores, mutant details, surviving mutants, and test improvement suggestions.",
"type": "object",
"required": ["skillName", "version", "timestamp", "status", "trustTier", "output"],
"properties": {
"skillName": {
"type": "string",
"const": "mutation-testing",
"description": "Skill name must be mutation-testing"
},
"version": {
"type": "string",
"pattern": "^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9]+)?$",
"description": "Semantic version of the skill"
},
"timestamp": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}",
"description": "ISO 8601 timestamp of output generation"
},
"status": {
"type": "string",
"enum": ["success", "partial", "failed", "skipped"],
"description": "Overall execution status"
},
"trustTier": {
"type": "integer",
"minimum": 0,
"maximum": 3,
"description": "Trust tier (0-3)"
},
"output": {
"type": "object",
"required": ["summary", "mutationScore", "mutants"],
"properties": {
"summary": {
"type": "string",
"minLength": 10,
"maxLength": 2000,
"description": "Human-readable summary of mutation testing results"
},
"mutationScore": {
"$ref": "#/$defs/mutationScore",
"description": "Overall mutation score and breakdown"
},
"mutants": {
"$ref": "#/$defs/mutantsSummary",
"description": "Summary of mutants generated and their statuses"
},
"survivors": {
"type": "array",
"items": {
"$ref": "#/$defs/survivingMutant"
},
"maxItems": 500,
"description": "List of surviving mutants requiring attention"
},
"operatorBreakdown": {
"type": "array",
"items": {
"$ref": "#/$defs/operatorStats"
},
"description": "Mutation score breakdown by operator type"
},
"fileBreakdown": {
"type": "array",
"items": {
"$ref": "#/$defs/fileStats"
},
"description": "Mutation score breakdown by source file"
},
"weakTests": {
"type": "array",
"items": {
"$ref": "#/$defs/weakTest"
},
"maxItems": 100,
"description": "Tests identified as weak based on mutation survival"
},
"recommendations": {
"type": "array",
"items": {
"$ref": "#/$defs/recommendation"
},
"maxItems": 50,
"description": "Test improvement recommendations"
},
"metrics": {
"$ref": "#/$defs/metrics",
"description": "Additional quantitative metrics"
},
"artifacts": {
"type": "array",
"items": {
"$ref": "#/$defs/artifact"
},
"maxItems": 20,
"description": "Generated artifacts (reports, logs)"
},
"testSuiteEffectiveness": {
"$ref": "#/$defs/testSuiteEffectiveness",
"description": "Test suite effectiveness metrics"
}
}
},
"metadata": {
"type": "object",
"properties": {
"executionTimeMs": {
"type": "integer",
"minimum": 0,
"maximum": 3600000,
"description": "Execution time in milliseconds"
},
"toolsUsed": {
"type": "array",
"items": {
"type": "string",
"enum": ["stryker", "pitest", "mutmut", "mull", "custom"]
},
"description": "Mutation testing tools used"
},
"agentId": {
"type": "string",
"pattern": "^qe-[a-z][a-z0-9-]*$",
"description": "ID of the agent that executed the skill"
},
"modelUsed": {
"type": "string",
"description": "LLM model used for analysis"
},
"inputHash": {
"type": "string",
"description": "Hash of input for caching"
},
"parentTaskId": {
"type": "string",
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
"description": "Parent task UUID if part of swarm"
},
"targetPath": {
"type": "string",
"description": "Path to source code under test"
},
"testPath": {
"type": "string",
"description": "Path to test suite"
},
"incremental": {
"type": "boolean",
"description": "Whether this was incremental mutation testing"
},
"changedLinesOnly": {
"type": "boolean",
"description": "Whether mutations were limited to changed lines"
}
}
},
"validation": {
"type": "object",
"properties": {
"schemaValid": {
"type": "boolean",
"description": "Whether output passes JSON schema validation"
},
"contentValid": {
"type": "boolean",
"description": "Whether output passes content validation"
},
"confidence": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Confidence score for output correctness"
},
"warnings": {
"type": "array",
"items": {
"type": "string",
"maxLength": 500
},
"maxItems": 20,
"description": "Validation warnings"
},
"errors": {
"type": "array",
"items": {
"type": "string",
"maxLength": 500
},
"maxItems": 20,
"description": "Validation errors"
}
}
},
"learning": {
"type": "object",
"properties": {
"patternsDetected": {
"type": "array",
"items": {
"type": "string"
},
"description": "Mutation patterns detected"
},
"reward": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Reward signal for learning"
},
"feedbackLoop": {
"type": "object",
"properties": {
"previousRunId": {
"type": "string",
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
},
"improvement": {
"type": "number",
"minimum": -1,
"maximum": 1
}
}
}
}
}
},
"$defs": {
"mutationScore": {
"type": "object",
"required": ["score", "killed", "survived", "total"],
"properties": {
"score": {
"type": "number",
"minimum": 0,
"maximum": 100,
"description": "Mutation score as percentage (0-100)"
},
"killed": {
"type": "integer",
"minimum": 0,
"description": "Number of mutants killed by tests"
},
"survived": {
"type": "integer",
"minimum": 0,
"description": "Number of mutants that survived"
},
"timeout": {
"type": "integer",
"minimum": 0,
"description": "Number of mutants that caused timeout"
},
"noCoverage": {
"type": "integer",
"minimum": 0,
"description": "Number of mutants with no test coverage"
},
"equivalent": {
"type": "integer",
"minimum": 0,
"description": "Number of equivalent mutants detected"
},
"total": {
"type": "integer",
"minimum": 0,
"description": "Total number of mutants generated"
},
"grade": {
"type": "string",
"pattern": "^[A-F][+-]?$",
"description": "Letter grade based on score"
},
"threshold": {
"type": "object",
"properties": {
"target": {
"type": "number",
"minimum": 0,
"maximum": 100,
"description": "Target mutation score"
},
"met": {
"type": "boolean",
"description": "Whether target was met"
}
}
},
"trend": {
"type": "string",
"enum": ["improving", "stable", "declining", "unknown"],
"description": "Trend compared to previous runs"
}
}
},
"mutantsSummary": {
"type": "object",
"required": ["total"],
"properties": {
"total": {
"type": "integer",
"minimum": 0,
"description": "Total mutants generated"
},
"byStatus": {
"type": "object",
"properties": {
"killed": { "type": "integer", "minimum": 0 },
"survived": { "type": "integer", "minimum": 0 },
"timeout": { "type": "integer", "minimum": 0 },
"noCoverage": { "type": "integer", "minimum": 0 },
"equivalent": { "type": "integer", "minimum": 0 },
"runtimeError": { "type": "integer", "minimum": 0 },
"compileError": { "type": "integer", "minimum": 0 }
}
},
"byOperator": {
"type": "object",
"additionalProperties": {
"type": "integer",
"minimum": 0
},
"description": "Count of mutants by operator type"
}
}
},
"survivingMutant": {
"type": "object",
"required": ["id", "operator", "location", "original", "mutated"],
"properties": {
"id": {
"type": "string",
"pattern": "^MUT-\\d{3,6}$",
"description": "Unique mutant identifier"
},
"operator": {
"type": "string",
"enum": [
"AOR", "AOD", "ROR", "LCR", "LOD", "COR", "COD",
"LVR", "RVR", "SDR", "UOR", "EMR", "ICR", "BCR",
"arithmetic", "relational", "logical", "conditional",
"return", "statement", "literal", "boundary", "other"
],
"description": "Mutation operator used"
},
"operatorDescription": {
"type": "string",
"maxLength": 200,
"description": "Human-readable description of operator"
},
"location": {
"$ref": "#/$defs/location",
"description": "Location of the mutation"
},
"original": {
"type": "string",
"maxLength": 1000,
"description": "Original code before mutation"
},
"mutated": {
"type": "string",
"maxLength": 1000,
"description": "Mutated code"
},
"impact": {
"type": "string",
"enum": ["critical", "high", "medium", "low"],
"description": "Potential impact of this mutation going undetected"
},
"impactDescription": {
"type": "string",
"maxLength": 500,
"description": "Description of potential impact"
},
"suggestedTest": {
"type": "string",
"maxLength": 2000,
"description": "Suggested test to kill this mutant"
},
"relatedTests": {
"type": "array",
"items": {
"type": "string"
},
"description": "Tests that cover but don't kill this mutant"
},
"equivalentSuspect": {
"type": "boolean",
"description": "Whether this might be an equivalent mutant"
}
}
},
"operatorStats": {
"type": "object",
"required": ["operator", "total", "killed", "score"],
"properties": {
"operator": {
"type": "string",
"description": "Mutation operator name"
},
"operatorCategory": {
"type": "string",
"enum": ["arithmetic", "relational", "logical", "conditional", "literal", "return", "statement", "other"],
"description": "Operator category"
},
"total": {
"type": "integer",
"minimum": 0,
"description": "Total mutants for this operator"
},
"killed": {
"type": "integer",
"minimum": 0,
"description": "Mutants killed"
},
"survived": {
"type": "integer",
"minimum": 0,
"description": "Mutants survived"
},
"score": {
"type": "number",
"minimum": 0,
"maximum": 100,
"description": "Score for this operator"
}
}
},
"fileStats": {
"type": "object",
"required": ["file", "total", "killed", "score"],
"properties": {
"file": {
"type": "string",
"description": "Source file path"
},
"total": {
"type": "integer",
"minimum": 0
},
"killed": {
"type": "integer",
"minimum": 0
},
"survived": {
"type": "integer",
"minimum": 0
},
"score": {
"type": "number",
"minimum": 0,
"maximum": 100
},
"priority": {
"type": "string",
"enum": ["critical", "high", "medium", "low"],
"description": "Priority for improvement"
}
}
},
"weakTest": {
"type": "object",
"required": ["testFile", "mutantsNotKilled"],
"properties": {
"testFile": {
"type": "string",
"description": "Test file path"
},
"testName": {
"type": "string",
"description": "Specific test name if applicable"
},
"mutantsNotKilled": {
"type": "integer",
"minimum": 1,
"description": "Number of mutants this test fails to kill"
},
"priority": {
"type": "string",
"enum": ["critical", "high", "medium", "low"],
"description": "Priority for improvement"
},
"reason": {
"type": "string",
"maxLength": 500,
"description": "Reason why test is weak"
},
"suggestions": {
"type": "array",
"items": {
"type": "string"
},
"description": "Suggestions to improve this test"
}
}
},
"recommendation": {
"type": "object",
"required": ["id", "title", "priority"],
"properties": {
"id": {
"type": "string",
"pattern": "^REC-\\d{3,6}$",
"description": "Unique recommendation identifier"
},
"title": {
"type": "string",
"minLength": 5,
"maxLength": 200,
"description": "Recommendation title"
},
"description": {
"type": "string",
"maxLength": 2000,
"description": "Detailed recommendation"
},
"priority": {
"type": "string",
"enum": ["critical", "high", "medium", "low"],
"description": "Priority level"
},
"effort": {
"type": "string",
"enum": ["trivial", "low", "medium", "high", "major"],
"description": "Estimated effort"
},
"impact": {
"type": "integer",
"minimum": 1,
"maximum": 10,
"description": "Expected impact score"
},
"relatedMutants": {
"type": "array",
"items": {
"type": "string",
"pattern": "^MUT-\\d{3,6}$"
},
"description": "IDs of related surviving mutants"
},
"codeExample": {
"type": "string",
"maxLength": 5000,
"description": "Example test code"
},
"targetFile": {
"type": "string",
"description": "File to add/modify tests in"
}
}
},
"metrics": {
"type": "object",
"properties": {
"coverageCorrelation": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Correlation between coverage and mutation score"
},
"assertionDensity": {
"type": "number",
"minimum": 0,
"description": "Average assertions per test"
},
"testEfficiency": {
"type": "number",
"minimum": 0,
"maximum": 100,
"description": "Percentage of tests that kill at least one mutant"
},
"avgMutantsPerFile": {
"type": "number",
"minimum": 0,
"description": "Average mutants per source file"
},
"avgTimePerMutant": {
"type": "integer",
"minimum": 0,
"description": "Average time to test each mutant (ms)"
},
"parallelWorkers": {
"type": "integer",
"minimum": 1,
"description": "Number of parallel workers used"
},
"custom": {
"type": "object",
"additionalProperties": true,
"description": "Custom metrics"
}
}
},
"testSuiteEffectiveness": {
"type": "object",
"properties": {
"overallRating": {
"type": "string",
"enum": ["excellent", "good", "fair", "poor"],
"description": "Overall test suite effectiveness rating"
},
"strengthAreas": {
"type": "array",
"items": {
"type": "string"
},
"description": "Areas where tests are strong"
},
"weaknessAreas": {
"type": "array",
"items": {
"type": "string"
},
"description": "Areas needing improvement"
},
"boundaryTesting": {
"type": "number",
"minimum": 0,
"maximum": 100,
"description": "Score for boundary value testing"
},
"conditionCoverage": {
"type": "number",
"minimum": 0,
"maximum": 100,
"description": "Score for condition/decision coverage"
},
"errorHandling": {
"type": "number",
"minimum": 0,
"maximum": 100,
"description": "Score for error handling testing"
}
}
},
"artifact": {
"type": "object",
"required": ["type", "path"],
"properties": {
"type": {
"type": "string",
"enum": ["report", "data", "log", "coverage", "html", "json"],
"description": "Artifact type"
},
"path": {
"type": "string",
"maxLength": 500,
"description": "Path to artifact"
},
"format": {
"type": "string",
"enum": ["json", "html", "md", "txt", "xml", "csv"],
"description": "Artifact format"
},
"description": {
"type": "string",
"maxLength": 500,
"description": "Artifact description"
},
"sizeBytes": {
"type": "integer",
"minimum": 0,
"description": "File size in bytes"
}
}
},
"location": {
"type": "object",
"required": ["file", "line"],
"properties": {
"file": {
"type": "string",
"maxLength": 500,
"description": "File path"
},
"line": {
"type": "integer",
"minimum": 1,
"description": "Line number"
},
"column": {
"type": "integer",
"minimum": 1,
"description": "Column number"
},
"endLine": {
"type": "integer",
"minimum": 1,
"description": "End line for multi-line mutations"
},
"endColumn": {
"type": "integer",
"minimum": 1,
"description": "End column"
},
"function": {
"type": "string",
"description": "Function name containing the mutation"
}
}
}
}
}
{
"skillName": "mutation-testing",
"skillVersion": "1.0.0",
"requiredTools": [
"jq"
],
"optionalTools": [
"stryker",
"pitest",
"mutmut",
"ajv",
"jsonschema",
"python3"
],
"schemaPath": "schemas/output.json",
"requiredFields": [
"skillName",
"status",
"output",
"output.mutationScore",
"output.mutants"
],
"requiredNonEmptyFields": [
"output.summary"
],
"mustContainTerms": [
"mutation",
"mutant",
"killed"
],
"mustNotContainTerms": [
"TODO",
"placeholder",
"undefined mutation score"
],
"enumValidations": {
".status": [
"success",
"partial",
"failed",
"skipped"
]
}
}
{
"skillName": "mutation-testing",
"version": "1.0.0",
"timestamp": "2026-02-02T12:00:00Z",
"status": "success",
"trustTier": 3,
"output": {
"summary": "Mutation testing completed for src/auth module. Generated 150 mutants across 8 files. Test suite killed 127 mutants (84.7% mutation score). Identified 5 weak tests requiring boundary value improvements.",
"mutationScore": {
"score": 84.67,
"killed": 127,
"survived": 18,
"timeout": 3,
"noCoverage": 1,
"equivalent": 1,
"total": 150,
"grade": "B",
"threshold": {
"target": 80,
"met": true
},
"trend": "improving"
},
"mutants": {
"total": 150,
"byStatus": {
"killed": 127,
"survived": 18,
"timeout": 3,
"noCoverage": 1,
"equivalent": 1,
"runtimeError": 0,
"compileError": 0
},
"byOperator": {
"AOR": 25,
"ROR": 45,
"LCR": 30,
"COR": 28,
"RVR": 22
}
},
"survivors": [
{
"id": "MUT-001",
"operator": "ROR",
"operatorDescription": "Relational Operator Replacement (>= to >)",
"location": {
"file": "src/auth/validator.ts",
"line": 45,
"column": 12,
"function": "validateAge"
},
"original": "if (age >= 18)",
"mutated": "if (age > 18)",
"impact": "high",
"impactDescription": "Edge case at exactly 18 years old would incorrectly fail validation",
"suggestedTest": "test('should validate user exactly 18 years old', () => { expect(validateAge(18)).toBe(true); });",
"relatedTests": ["should validate adult", "should reject minor"],
"equivalentSuspect": false
},
{
"id": "MUT-002",
"operator": "LCR",
"operatorDescription": "Logical Connector Replacement (&& to ||)",
"location": {
"file": "src/auth/permissions.ts",
"line": 28,
"column": 8,
"function": "canAccess"
},
"original": "isAdmin && hasPermission",
"mutated": "isAdmin || hasPermission",
"impact": "critical",
"impactDescription": "Would allow unauthorized access if only one condition is true",
"suggestedTest": "test('should deny access when only admin flag is set', () => { expect(canAccess({ isAdmin: true, hasPermission: false })).toBe(false); });",
"relatedTests": ["should allow admin access"],
"equivalentSuspect": false
},
{
"id": "MUT-003",
"operator": "conditional",
"operatorDescription": "Conditional boundary mutation",
"location": {
"file": "src/auth/session.ts",
"line": 67,
"column": 6,
"function": "isSessionValid"
},
"original": "if (expiresAt > now)",
"mutated": "if (expiresAt >= now)",
"impact": "medium",
"impactDescription": "Session might be considered valid at exact expiration moment",
"suggestedTest": "test('should invalidate session at exact expiration time', () => { const now = Date.now(); expect(isSessionValid({ expiresAt: now })).toBe(false); });",
"relatedTests": ["should validate active session"],
"equivalentSuspect": false
}
],
"operatorBreakdown": [
{
"operator": "AOR",
"operatorCategory": "arithmetic",
"total": 25,
"killed": 24,
"survived": 1,
"score": 96.0
},
{
"operator": "ROR",
"operatorCategory": "relational",
"total": 45,
"killed": 36,
"survived": 8,
"score": 80.0
},
{
"operator": "LCR",
"operatorCategory": "logical",
"total": 30,
"killed": 25,
"survived": 5,
"score": 83.3
},
{
"operator": "COR",
"operatorCategory": "conditional",
"total": 28,
"killed": 24,
"survived": 3,
"score": 85.7
},
{
"operator": "RVR",
"operatorCategory": "return",
"total": 22,
"killed": 18,
"survived": 1,
"score": 81.8
}
],
"fileBreakdown": [
{
"file": "src/auth/validator.ts",
"total": 35,
"killed": 28,
"survived": 6,
"score": 80.0,
"priority": "high"
},
{
"file": "src/auth/permissions.ts",
"total": 28,
"killed": 22,
"survived": 5,
"score": 78.6,
"priority": "high"
},
{
"file": "src/auth/session.ts",
"total": 25,
"killed": 21,
"survived": 3,
"score": 84.0,
"priority": "medium"
}
],
"weakTests": [
{
"testFile": "tests/auth/validator.test.ts",
"mutantsNotKilled": 6,
"priority": "high",
"reason": "Missing boundary value tests for age validation",
"suggestions": [
"Add test for exactly 18 years old",
"Add test for age = 0",
"Add test for maximum age boundary"
]
},
{
"testFile": "tests/auth/permissions.test.ts",
"mutantsNotKilled": 5,
"priority": "high",
"reason": "Incomplete logical condition coverage",
"suggestions": [
"Test all combinations of admin and permission flags",
"Add negative tests for partial conditions"
]
},
{
"testFile": "tests/auth/session.test.ts",
"mutantsNotKilled": 3,
"priority": "medium",
"reason": "Missing exact boundary tests for session expiration",
"suggestions": [
"Test session validity at exact expiration time"
]
}
],
"recommendations": [
{
"id": "REC-001",
"title": "Add boundary value tests for age validation",
"description": "The validator.ts file has multiple surviving relational operator mutations. Add tests for exact boundary values (18, 0, max age).",
"priority": "high",
"effort": "low",
"impact": 8,
"relatedMutants": ["MUT-001"],
"codeExample": "test('should validate exact boundary ages', () => {\n expect(validateAge(18)).toBe(true);\n expect(validateAge(17)).toBe(false);\n});",
"targetFile": "tests/auth/validator.test.ts"
},
{
"id": "REC-002",
"title": "Add combinatorial tests for permission logic",
"description": "The permissions.ts file has surviving logical operator mutations. Test all combinations of boolean conditions.",
"priority": "critical",
"effort": "medium",
"impact": 9,
"relatedMutants": ["MUT-002"],
"targetFile": "tests/auth/permissions.test.ts"
},
{
"id": "REC-003",
"title": "Add session expiration edge case tests",
"description": "Test session validity at the exact moment of expiration.",
"priority": "medium",
"effort": "low",
"impact": 6,
"relatedMutants": ["MUT-003"],
"targetFile": "tests/auth/session.test.ts"
}
],
"metrics": {
"coverageCorrelation": 0.72,
"assertionDensity": 3.2,
"testEfficiency": 89.5,
"avgMutantsPerFile": 18.75,
"avgTimePerMutant": 245,
"parallelWorkers": 8
},
"testSuiteEffectiveness": {
"overallRating": "good",
"strengthAreas": [
"Good arithmetic operator coverage",
"Strong return value testing"
],
"weaknessAreas": [
"Boundary value testing needs improvement",
"Logical condition combinations incomplete"
],
"boundaryTesting": 72,
"conditionCoverage": 78,
"errorHandling": 85
},
"artifacts": [
{
"type": "report",
"path": "reports/mutation/mutation-report.html",
"format": "html",
"description": "Interactive HTML mutation testing report",
"sizeBytes": 245678
},
{
"type": "data",
"path": "reports/mutation/mutation-results.json",
"format": "json",
"description": "Raw mutation testing data",
"sizeBytes": 89234
}
]
},
"metadata": {
"executionTimeMs": 125430,
"toolsUsed": ["stryker"],
"agentId": "qe-mutation-tester",
"modelUsed": "claude-sonnet-4-6",
"targetPath": "src/auth",
"testPath": "tests/auth",
"incremental": false,
"changedLinesOnly": false
},
"validation": {
"schemaValid": true,
"contentValid": true,
"confidence": 0.92,
"warnings": []
},
"learning": {
"patternsDetected": [
"boundary-value-weakness",
"logical-condition-gaps",
"high-arithmetic-coverage"
],
"reward": 0.85
}
}
Related skills
FAQ
What does mutation-testing do?
mutation-testing is a Claude Code skill for testing & qa.
When should I use mutation-testing?
When you need to helps with testing & qa tasks., or when mutation-testing is a claude code skill for testing & qa.
What are the main capabilities?
mutation-testing; Testing & QA; AI-coding skill.