mutation-testing
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseMutation Testing
Mutation Testing
<default_to_action>
When validating test quality or improving test effectiveness:
- MUTATE code (change + to -, >= to >, remove statements)
- RUN tests against each mutant
- VERIFY tests catch mutations (kill mutants)
- IDENTIFY surviving mutants (tests need improvement)
- 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>
<default_to_action>
在验证测试质量或提升测试有效性时:
- 对代码进行MUTATE(突变)操作(将+改为-,>=改为>,移除语句等)
- 针对每个突变体运行测试
- 验证测试是否能发现突变(杀死突变体)
- 识别存活的突变体(对应的测试需要优化)
- 强化测试以杀死存活的突变体
快速Mutation指标:
- Mutation Score(突变分数)= 被杀死的突变体数 /(被杀死的突变体数 + 存活的突变体数)
- 目标:Mutation Score > 80%
- 存活的突变体 = 薄弱的测试
关键成功要素:
- 高覆盖率 ≠ 优质测试(比如100%覆盖率但0%断言)
- Mutation Testing可证明测试确实能发现漏洞
- 优先关注关键代码路径 </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
Mutation Score 解读
| Score | Interpretation |
|---|---|
| 90%+ | Excellent test quality |
| 80-90% | Good, minor improvements |
| 60-80% | Needs attention |
| < 60% | Significant gaps |
| 分数 | 解读 |
|---|---|
| 90%+ | 测试质量极佳 |
| 80-90% | 良好,需小幅优化 |
| 60-80% | 需要重点关注 |
| < 60% | 存在重大漏洞 |
Common Mutation Operators
常见Mutation操作符
| Category | Original | Mutant |
|---|---|---|
| Arithmetic | | |
| Relational | | |
| Logical | | |
| Conditional | | |
| Statement | | (removed) |
| 类别 | 原始代码 | 突变体 |
|---|---|---|
| 算术运算 | | |
| 关系运算 | | |
| 逻辑运算 | | `a |
| 条件判断 | | |
| 语句修改 | | (已移除) |
How Mutation Testing Works
Mutation Testing的工作原理
javascript
// 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 valuejavascript
// 原始代码
function isAdult(age) {
return age >= 18; // ← 突变体:将 >= 改为 >
}
// 强测试(可发现突变)
test('18 is adult', () => {
expect(isAdult(18)).toBe(true); // 杀死突变体!
});
// 弱测试(突变体存活)
test('19 is adult', () => {
expect(isAdult(19)).toBe(true); // 无法区分 >= 和 >
});
// 存活的突变体 → 测试需要添加边界值用例Using Stryker
使用Stryker
bash
undefinedbash
undefinedInstall
安装
npm install --save-dev @stryker-mutator/core @stryker-mutator/jest-runner
npm install --save-dev @stryker-mutator/core @stryker-mutator/jest-runner
Initialize
初始化
npx stryker init
**Configuration:**
```json
{
"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:
bash
npx stryker runOutput:
Mutation Score: 87.3%
Killed: 124
Survived: 18
No Coverage: 3
Timeout: 1npx stryker init
**配置:**
```json
{
"packageManager": "npm",
"reporters": ["html", "clear-text", "progress"],
"testRunner": "jest",
"coverageAnalysis": "perTest",
"mutate": [
"src/**/*.ts",
"!src/**/*.spec.ts"
],
"thresholds": {
"high": 90,
"low": 70,
"break": 60
}
}运行:
bash
npx stryker run输出:
Mutation Score: 87.3%
Killed: 124
Survived: 18
No Coverage: 3
Timeout: 1Fixing Surviving Mutants
修复存活的突变体
javascript
// 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
});javascript
// 存活的突变体:>= 被改为 >
function calculateDiscount(quantity) {
if (quantity >= 10) { // 突变体存活!
return 0.1;
}
return 0;
}
// 原始的弱测试
test('large order gets discount', () => {
expect(calculateDiscount(15)).toBe(0.1); // 未测试边界值
});
// 修复:添加边界测试
test('exactly 10 gets discount', () => {
expect(calculateDiscount(10)).toBe(0.1); // 杀死突变体!
});
test('9 does not get discount', () => {
expect(calculateDiscount(9)).toBe(0); // 测试边界值以下的情况
});Agent-Driven Mutation Testing
基于Agent的Mutation Testing
typescript
// 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");typescript
// 分析Mutation Score并生成修复方案
await Task("Mutation Analysis", {
targetFile: 'src/payment.ts',
generateMissingTests: true,
minScore: 80
}, "qe-test-generator");
// 返回结果:
// {
// mutationScore: 0.65,
// survivedMutations: [
// { line: 45, operator: '>=', mutant: '>', killedBy: null }
// ],
// generatedTests: [
// 'test for boundary at line 45'
// ]
// }
// 覆盖率与突变的关联分析
await Task("Coverage Quality Analysis", {
coverageData: coverageReport,
mutationData: mutationReport,
identifyWeakCoverage: true
}, "qe-coverage-analyzer");Agent Coordination Hints
Agent协作提示
Memory Namespace
内存命名空间
aqe/mutation-testing/
├── mutation-results/* - Stryker reports
├── surviving/* - Surviving mutants
├── generated-tests/* - Tests to kill mutants
└── trends/* - Mutation score over timeaqe/mutation-testing/
├── mutation-results/* - Stryker报告
├── surviving/* - 存活的突变体
├── generated-tests/* - 用于杀死突变体的测试用例
└── trends/* - Mutation Score变化趋势Fleet Coordination
集群协作
typescript
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'
});typescript
const mutationFleet = await FleetManager.coordinate({
strategy: 'mutation-testing',
agents: [
'qe-test-generator', // 为存活突变体生成测试用例
'qe-coverage-analyzer', // 覆盖率关联分析
'qe-quality-analyzer' // 质量评估
],
topology: 'sequential'
});Related Skills
相关技能
- tdd-london-chicago - Write effective tests first
- test-design-techniques - Boundary value analysis
- quality-metrics - Measure test effectiveness
- tdd-london-chicago - 先编写高效的测试用例
- test-design-techniques - 边界值分析
- quality-metrics - 评估测试有效性
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.
高代码覆盖率 ≠ 优质测试。100%覆盖率但断言薄弱的测试毫无用处。Mutation Testing可证明测试确实能发现漏洞。
优先关注关键路径。不要对所有代码都进行突变测试——优先处理支付、认证、数据完整性相关代码。
借助Agent: Agent可运行突变分析、识别存活的突变体,并生成缺失的测试用例来杀死这些突变体,实现测试质量的自动化提升。