mutation-testing
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAI-Powered Mutation Testing
AI驱动的Mutation Testing
Target: $ARGUMENTS
If no argument provided, default to files changed in the current branch (via ).
git diffThis skill implements the mutation testing workflow: generate targeted mutants, filter unproductive ones, run tests to find survivors, and harden the test suite by strengthening or creating tests that kill surviving mutants.
目标:$ARGUMENTS
如果未提供参数,默认使用当前分支中变更的文件(通过获取)。
git diff此技能实现了Mutation Testing工作流:生成针对性的变异体,过滤无效变异体,运行测试找出存活的变异体,并通过强化或创建能消灭存活变异体的测试来加固测试套件。
Step 1: Gather Context
步骤1:收集上下文信息
1a. Identify Target Files
1a. 确定目标文件
Determine what to mutate based on :
$ARGUMENTS- File path — Mutate the specified source file
- Directory — Mutate source files in the directory (exclude test files)
- No argument — Use git diff to find changed source files:
bash
git diff --name-only $(git merge-base HEAD main)...HEAD -- '*.ts' '*.tsx' ':!*.spec.*' ':!*.test.*'
If no target files found, notify the user and stop.
根据确定要变异的对象:
$ARGUMENTS- 文件路径 — 对指定的源文件进行变异
- 目录 — 对目录中的源文件进行变异(排除测试文件)
- 无参数 — 使用git diff查找变更的源文件:
bash
git diff --name-only $(git merge-base HEAD main)...HEAD -- '*.ts' '*.tsx' ':!*.spec.*' ':!*.test.*'
如果未找到目标文件,通知用户并终止流程。
1b. Gather Supporting Context
1b. 收集辅助上下文信息
For each target source file, collect:
- Source code — Read the full file contents
- Existing tests — Find corresponding test files (,
*.spec.ts) via naming convention or import analysis*.test.ts - Test coverage — Run tests with coverage for the target file to identify uncovered lines:
bash
bun run test -- --coverage --collectCoverageFrom='<target-file>' --silent 2>&1 | tail -20 - Recent git history — Check for recent defects or frequent changes:
bash
git log --oneline -10 -- <target-file> - Risk factors — Assess which risk factors apply to each file:
| Risk Factor | Indicators |
|---|---|
| Data security / compliance | Handles PII, auth, authorization, encryption, tokens |
| Integrations | External API calls, HTTP clients, webhooks, message queues |
| Code vs data model | Database queries, ORM entities, schema validation |
| Historic defects | Frequent bug-fix commits, complex conditional logic |
| Change impact | Exported utility functions, shared modules, base classes |
| Performance | Loops over large datasets, recursive calls, caching logic |
针对每个目标源文件,收集以下信息:
- 源代码 — 读取文件的完整内容
- 现有测试 — 通过命名约定或导入分析找到对应的测试文件(、
*.spec.ts)*.test.ts - 测试覆盖率 — 运行带覆盖率统计的测试,识别目标文件中未被覆盖的代码行:
bash
bun run test -- --coverage --collectCoverageFrom='<target-file>' --silent 2>&1 | tail -20 - 近期Git历史 — 检查近期的缺陷修复或频繁变更:
bash
git log --oneline -10 -- <target-file> - 风险因素 — 评估每个文件对应的风险因素:
| 风险因素 | 识别指标 |
|---|---|
| 数据安全/合规 | 处理PII、auth、授权、加密、令牌 |
| 集成 | 外部API调用、HTTP客户端、Webhook、消息队列 |
| 代码与数据模型 | 数据库查询、ORM实体、schema验证 |
| 历史缺陷 | 频繁的bug修复提交、复杂条件逻辑 |
| 变更影响 | 导出的工具函数、共享模块、基类 |
| 性能 | 遍历大型数据集、递归调用、缓存逻辑 |
1c. Determine Test Runner
1c. 确定测试运行器
Detect the project's test framework from scripts and devDependencies:
package.json- Jest:
bun run test - Vitest:
bun run test - Other: adapt accordingly
从的脚本和devDependencies中检测项目的测试框架:
package.json- Jest:
bun run test - Vitest:
bun run test - 其他:相应调整
Step 2: Generate Mutants
步骤2:生成变异体
2a. Create Experimental Branch
2a. 创建实验分支
bash
git stash --include-untracked || true
git checkout -b mutation-testing/$(date +%Y-%m-%d-%H%M%S)
git stash pop || truebash
git stash --include-untracked || true
git checkout -b mutation-testing/$(date +%Y-%m-%d-%H%M%S)
git stash pop || true2b. Generate Risk-Factor-Guided Mutants
2b. 生成基于风险因素的变异体
For each target source file, generate 3-5 mutants that target the identified risk factors. Apply these mutation operators:
| Operator Type | Examples |
|---|---|
| Decision mutations | Change |
| Value mutations | Change constants, swap string literals, alter numeric values |
| Statement mutations | Remove guard clauses, delete error handling, skip validation |
| Integration mutations | Remove timeout handling, skip error code checks, bypass retry logic |
| Security mutations | Remove auth checks, bypass input validation, expose sensitive data in logs |
For each mutant, produce:
- Mutant ID — Sequential identifier (M001, M002, etc.)
- File and line — Exact location of the change
- Mutation description — What was changed and why
- Risk factor — Which risk factor this targets
- The code change — A minimal, atomic edit to introduce the defect
Mutant quality criteria — Each mutant must be:
- Non-trivial — Not just whitespace, comments, or formatting
- Buildable — The project must still compile/typecheck
- Realistic — Simulates a plausible programming error
- Targeted — Addresses a specific risk factor
- Atomic — Exactly one logical change per mutant
针对每个目标源文件,生成3-5个针对已识别风险因素的变异体。应用以下变异操作符:
| 操作符类型 | 示例 |
|---|---|
| 决策变异 | 将 |
| 值变异 | 修改常量、交换字符串字面量、更改数值 |
| 语句变异 | 移除守卫子句、删除错误处理、跳过验证 |
| 集成变异 | 移除超时处理、跳过错误码检查、绕过重试逻辑 |
| 安全变异 | 移除认证检查、绕过输入验证、在日志中暴露敏感数据 |
针对每个变异体,生成以下信息:
- 变异体ID — 顺序标识符(如M001、M002等)
- 文件与行号 — 变更的精确位置
- 变异描述 — 变更内容及原因
- 风险因素 — 针对的风险因素
- 代码变更 — 引入缺陷的最小原子性修改
变异体质量标准 — 每个变异体必须满足:
- 非琐碎 — 不能仅为空白、注释或格式变更
- 可构建 — 项目仍能编译/类型检查通过
- 真实可信 — 模拟合理的编程错误
- 针对性 — 针对特定风险因素
- 原子性 — 每个变异体仅包含一个逻辑变更
2c. Apply and Validate Each Mutant
2c. 应用并验证每个变异体
For each generated mutant, one at a time:
- Apply the mutation — Edit the source file to introduce the defect
- Build check — Run to verify the project still compiles
bun run typecheck- If build fails: discard the mutant, revert the change, log failure reason, continue to next
- Commit the mutant —
git commit -am "mutant: M00X - <description>"
针对每个生成的变异体,依次执行以下操作:
- 应用变异 — 编辑源文件以引入缺陷
- 构建检查 — 运行验证项目仍可编译
bun run typecheck- 若构建失败:丢弃该变异体,回滚变更,记录失败原因,继续下一个
- 提交变异体 — 执行
git commit -am "mutant: M00X - <description>"
Step 3: Filter Mutants
步骤3:过滤变异体
3a. Run Tests Against Each Mutant
3a. 针对每个变异体运行测试
Process mutants in reverse order (LIFO — latest commit first):
- Run relevant tests against the mutant:
bash
bun run test -- <test-file-path> --silent 2>&1 - Evaluate result:
- Test fails (mutant killed) → Revert the mutant commit. Log as killed. Proceed to next mutant.
- Test passes (mutant survived) → The mutant reveals a test gap. Keep it for Step 4.
按逆序处理变异体(后进先出LIFO — 最新提交优先):
- 针对变异体运行相关测试:
bash
bun run test -- <test-file-path> --silent 2>&1 - 评估结果:
- 测试失败(变异体被消灭)→ 回滚变异体提交,记录为已消灭,继续下一个变异体。
- 测试通过(变异体存活)→ 该变异体暴露了测试缺口,保留至步骤4处理。
3b. Equivalence Detection for Surviving Mutants
3b. 存活变异体的等价性检测
For each surviving mutant, verify it is not semantically equivalent to the original:
- AST-level comparison — Compare the diff. If the change is purely syntactic (reordering independent statements, renaming to equivalent aliases), discard it.
- Behavioral analysis — Reason about whether any input could distinguish the mutant from the original:
- If no distinguishing input exists → Discard as equivalent
- If a distinguishing input exists → Keep as a unique actionable mutant
- If uncertain → Keep and flag for human review
针对每个存活的变异体,验证其与原始代码在语义上不等价:
- AST层级比较 — 比较差异。若变更仅为语法层面(如重排独立语句、重命名为等价别名),则丢弃该变异体。
- 行为分析 — 判断是否存在输入能区分变异体与原始代码:
- 若不存在区分输入 → 判定为等价并丢弃
- 若存在区分输入 → 保留为可处理的唯一变异体
- 若无法确定 → 保留并标记为需人工审核
3c. Record Mutant Metadata
3c. 记录变异体元数据
For each mutant, maintain a record:
json
{
"mutant_id": "M001",
"file": "<source-file>",
"line": 42,
"risk_factor": "Data security / compliance",
"description": "Removed authentication check before data access",
"status": "survived|killed|equivalent|discarded",
"commit_hash": "<hash>",
"tests_run": ["test-file.spec.ts"],
"equivalence_result": "not_equivalent|equivalent|uncertain"
}Print a summary table after filtering:
| Mutant | File | Risk Factor | Status |
|--------|------|-------------|--------|
| M001 | ... | ... | survived |
| M002 | ... | ... | killed |针对每个变异体,维护以下记录:
json
{
"mutant_id": "M001",
"file": "<source-file>",
"line": 42,
"risk_factor": "Data security / compliance",
"description": "Removed authentication check before data access",
"status": "survived|killed|equivalent|discarded",
"commit_hash": "<hash>",
"tests_run": ["test-file.spec.ts"],
"equivalence_result": "not_equivalent|equivalent|uncertain"
}过滤完成后打印汇总表格:
| Mutant | File | Risk Factor | Status |
|--------|------|-------------|--------|
| M001 | ... | ... | survived |
| M002 | ... | ... | killed |Step 4: Harden Test Suite
步骤4:加固测试套件
For each surviving, non-equivalent mutant:
针对每个存活且非等价的变异体:
4a. Determine Test Strategy
4a. 确定测试策略
- Existing test covers the mutated region → Strengthen the existing test
- No test covers the mutated region → Generate a new test
- 现有测试覆盖变异区域 → 强化现有测试
- 无测试覆盖变异区域 → 生成新测试
4b. Strengthen Existing Test or Generate New Test
4b. 强化现有测试或生成新测试
When strengthening an existing test, modify the test to:
- Add assertions that detect the behavioral difference introduced by the mutant
- Add or modify test inputs that expose the defect in the mutant code
- Preserve the test method name, signature, and overall structure
- Avoid adding trivial or unrelated checks
When generating a new test, create a test that:
- Specifically exercises the behavioral difference between original and mutant code
- Uses strong, precise assertions that detect the exact defect
- Focuses on the identified risk factor
- Includes realistic test data that exposes the mutant's flawed behavior
- Follows existing test naming conventions and structure from the codebase
强化现有测试时,修改测试以实现:
- 添加断言以检测变异体引入的行为差异
- 添加或修改测试输入以暴露变异体代码中的缺陷
- 保留测试方法名称、签名及整体结构
- 避免添加琐碎或无关的检查
生成新测试时,创建的测试需满足:
- 专门针对原始代码与变异体代码的行为差异
- 使用强而精确的断言以检测确切缺陷
- 聚焦于已识别的风险因素
- 包含能暴露变异体缺陷行为的真实测试数据
- 遵循代码库中现有的测试命名约定和结构
4c. Validate Each Test (3-attempt limit)
4c. 验证每个测试(最多3次尝试)
For each improved or new test, validate with up to 3 attempts:
- Revert the mutant — Switch to original code
- Build check — Ensure the test compiles
- Run on original code — Test must PASS on unmodified code
- Re-apply the mutant — Switch back to mutated code
- Run on mutant code — Test must FAIL on the mutant
If validation fails, refine the test (up to 3 total attempts). If still failing after 3 attempts, flag for manual review.
针对每个改进或新增的测试,最多尝试3次验证:
- 回滚变异体 — 切换回原始代码
- 构建检查 — 确保测试可编译
- 在原始代码上运行 — 测试必须在未修改的代码上通过
- 重新应用变异体 — 切换回变异后的代码
- 在变异体代码上运行 — 测试必须在变异体上失败
若验证失败,优化测试(最多3次尝试)。若3次尝试后仍失败,标记为需人工审核。
4d. Apply Decision Matrix
4d. 应用决策矩阵
Classify each test result:
| Original Code | Mutant Code | Signal | Action |
|---|---|---|---|
| Builds + Passes | Builds + Fails | Strong detection | Keep — alert developer |
| Builds + Passes | Builds + Passes | Weak assertion | Refine — strengthen assertion |
| Builds + Fails | Builds + Passes | Bad test | Discard — generate new test |
| Doesn't build | Any | Broken test | Discard — generate new test |
| Builds + Passes | Doesn't build | Untestable mutant | Discard — notify developer |
| Builds + Fails | Builds + Fails | Ambiguous signal | Discard — generate new test |
对每个测试结果进行分类:
| 原始代码状态 | 变异体代码状态 | 信号 | 操作 |
|---|---|---|---|
| 可构建 + 测试通过 | 可构建 + 测试失败 | 强检测 | 保留 — 通知开发者 |
| 可构建 + 测试通过 | 可构建 + 测试通过 | 弱断言 | 优化 — 强化断言 |
| 可构建 + 测试失败 | 可构建 + 测试通过 | 无效测试 | 丢弃 — 生成新测试 |
| 无法构建 | 任意状态 | 损坏的测试 | 丢弃 — 生成新测试 |
| 可构建 + 测试通过 | 无法构建 | 不可测试的变异体 | 丢弃 — 通知开发者 |
| 可构建 + 测试失败 | 可构建 + 测试失败 | 模糊信号 | 丢弃 — 生成新测试 |
4e. Finalize Tests
4e. 最终确定测试
For each validated test:
- Add an inline comment above the test referencing the mutant:
typescript
// Test hardened to kill mutant M001 (Risk Factor: Data security / compliance) - Commit the test improvement to the experimental branch
针对每个验证通过的测试:
- 在测试上方添加内联注释,引用对应的变异体:
typescript
// Test hardened to kill mutant M001 (Risk Factor: Data security / compliance) - 将测试改进提交到实验分支
Step 5: Cleanup and Report
步骤5:清理与报告
5a. Revert All Mutants
5a. 回滚所有变异体
Remove all mutant commits from the experimental branch, keeping only test improvements:
bash
undefined从实验分支中移除所有变异体提交,仅保留测试改进:
bash
undefinedRevert mutant commits (identified by "mutant:" prefix in commit message)
Revert mutant commits (identified by "mutant:" prefix in commit message)
git log --oneline | grep "^.* mutant:" | awk '{print $1}' | while read hash; do
git revert --no-commit "$hash"
done
git commit -m "chore: revert all mutants after test hardening"
undefinedgit log --oneline | grep "^.* mutant:" | awk '{print $1}' | while read hash; do
git revert --no-commit "$hash"
done
git commit -m "chore: revert all mutants after test hardening"
undefined5b. Validate Clean State
5b. 验证干净状态
- Run full test suite on the clean code with test improvements:
bash
bun run test 2>&1 - All tests must pass. If any fail, investigate and fix.
- 在包含测试改进的干净代码上运行完整测试套件:
bash
bun run test 2>&1 - 所有测试必须通过。若有失败,调查并修复。
5c. Report Results
5c. 报告结果
Print a comprehensive mutation testing report:
undefined打印一份全面的Mutation Testing报告:
undefinedMutation Testing Report
Mutation Testing报告
Target: <files tested>
Date: <timestamp>
Branch: <experimental branch name>
目标: <files tested>
日期: <timestamp>
分支: <experimental branch name>
Summary
摘要
- Total mutants generated: X
- Killed by existing tests: X
- Survived (test gaps found): X
- Equivalent (discarded): X
- Build failures (discarded): X
- Mutation Score: X% (killed / (total - equivalent))
- 生成的变异体总数: X
- 被现有测试消灭的变异体: X
- 存活的变异体(发现测试缺口): X
- 等价变异体(已丢弃): X
- 构建失败的变异体(已丢弃): X
- Mutation Score: X% (killed / (total - equivalent))
Test Improvements
测试改进
- Tests strengthened: X
- New tests generated: X
- Tests validated successfully: X
- Tests requiring manual review: X
- 强化的测试数量: X
- 生成的新测试数量: X
- 验证成功的测试数量: X
- 需人工审核的测试数量: X
Surviving Mutants (Unresolved)
存活变异体(未解决)
| Mutant | File | Line | Risk Factor | Description |
|---|---|---|---|---|
| M00X | ... | ... | ... | ... |
| Mutant | File | Line | Risk Factor | Description |
|---|---|---|---|---|
| M00X | ... | ... | ... | ... |
Oracle Gap
Oracle缺口
- Code coverage: X%
- Mutation score: X%
- Oracle gap: X% (coverage - mutation score)
- 代码覆盖率: X%
- Mutation score: X%
- Oracle gap: X% (coverage - mutation score)
Risk Factor Coverage
风险因素覆盖情况
| Risk Factor | Mutants | Killed | Survived | Score |
|---|---|---|---|---|
| Data security | X | X | X | X% |
| Integrations | X | X | X | X% |
undefined| Risk Factor | Mutants | Killed | Survived | Score |
|---|---|---|---|---|
| Data security | X | X | X | X% |
| Integrations | X | X | X | X% |
undefined5d. Present Options
5d. 提供操作选项
Ask the user:
- Merge test improvements — Cherry-pick test commits to the original branch, delete experimental branch
- Keep experimental branch — For further review before merging
- Discard everything — Delete the experimental branch, no changes kept
If the user chooses to merge:
bash
git checkout <original-branch>
git cherry-pick <test-improvement-commits>
git branch -D <experimental-branch>询问用户:
- 合并测试改进 — 将测试提交拣选到原始分支,删除实验分支
- 保留实验分支 — 供合并前进一步审核
- 全部丢弃 — 删除实验分支,不保留任何变更
若用户选择合并:
bash
git checkout <original-branch>
git cherry-pick <test-improvement-commits>
git branch -D <experimental-branch>Never
禁止操作
- Modify test files to make them pass on mutants (defeats the purpose)
- Generate mutants in test files (only mutate source code)
- Skip the build check after generating a mutant
- Commit mutants to protected branches (dev, staging, main)
- Leave mutant code in the codebase after completion
- Generate more than 5 mutants per file (diminishing returns)
- Skip equivalence detection for surviving mutants
- Mark a test as valid without running it on both original and mutant code
- Use with any git command
--no-verify
- 修改测试文件使其在变异体上通过(违背测试目的)
- 在测试文件中生成变异体(仅对源代码进行变异)
- 生成变异体后跳过构建检查
- 将变异体提交到受保护分支(如dev、staging、main)
- 完成后将变异体代码留在代码库中
- 每个文件生成超过5个变异体(收益递减)
- 跳过存活变异体的等价性检测
- 未在原始代码和变异体代码上都运行就标记测试有效
- 在任何git命令中使用
--no-verify