Skip to content

最佳实践

基于 StrykerJS v9.6 编写

速查

  • 别全仓跑:用 mutate 圈定核心业务逻辑 / 工具函数 / 校验器,UI / 样板 / 生成代码排除
  • 分数当信号不当 KPI:用来发现盲区、指导补断言,别盲目追 100%(等价变异体令 100% 常不可达)
  • 与覆盖率互补,顺序:先覆盖率 → 后变异:覆盖率保「执行到」(便宜快),变异保「断言强」(贵慢)
  • CI 门禁靠 thresholds.break:设 break(如 60)低于即退出码 1;默认 null 不会 fail
  • 等价变异体显式 disable 并写 reason,保持可追溯
  • 反模式:全仓无差别跑 / 把分数当硬 KPI 强制 100% / 跳过覆盖率直接上 / 默认 break:null 还以为会卡 / 对 UI 跑变异 / 把烂测试当等价变异体 disable

挑核心逻辑跑,别全仓

变异测试慢一两个数量级,全仓无差别跑几乎不可行。用 mutate glob 精确圈定值得跑的代码:

json
"mutate": [
  "src/utils/**/*.ts",        // 工具函数
  "src/validators/**/*.ts",   // 校验器
  "src/stores/**/*.ts",       // Pinia store 的纯逻辑
  "!src/**/*.{spec,test}.ts"
]
  • 值得跑:核心业务逻辑、工具函数、校验器(validators)、计算密集 / 算法逻辑——这些 bug 代价高、断言价值大。
  • 不值得跑:UI 组件、纯展示层、样板代码、自动生成代码——产出大量低价值 survived(样式、字符串字面量),噪音淹没真问题。

分数当信号,不当 KPI

  • 变异分数用来发现测试盲区、指导补断言,是「质量信号」。
  • 不要为了刷分数硬写无意义测试,也别盲目追 100%——等价变异体(变异后功能与原码完全等价、任何测试都杀不死)使 100% 往往不可达(见 变异体与算子)。
  • 合理目标:核心逻辑给一个有意义的下限(如 70-85%),把精力花在「真盲区」而非「凑满分」。

与覆盖率互补:先覆盖率,后变异

覆盖率叶与变异测试是「广度 → 深度」的递进,不是替代关系:

阶段工具保证成本
代码覆盖率代码被执行到(广度)便宜、快
变异测试测试断言够强(深度)贵、慢
✅ 正确顺序:先用覆盖率补齐「跑到」→ 再用变异测试补强「断言」
❌ 错误顺序:跳过覆盖率直接上变异 → 在大量 no coverage 上浪费算力

先用覆盖率(便宜)保证代码被跑到,把 no coverage 降下来,再上变异测试(贵)专攻「有覆盖但断言弱」的假绿测试,算力花在刀刃上。

CI 用 break 门禁

json
"thresholds": { "high": 80, "low": 60, "break": 60 }
  • ⚠️ CI 门禁只认 thresholds.break:分数 < break → 退出码 1 卡住合并。high / low 只染色不影响退出码
  • ⚠️ 默认 break: null 永远不会让构建失败——想卡 CI 必须显式设值(高频陷阱)。
  • 本地探索可不设 break(默认 null)随便跑;CI 才挂门禁。
  • incremental + perTest + concurrency 控制 CI 时长,增量文件(reports/stryker-incremental.json)纳入缓存(见 Vue/TS 实战)。

等价变异体显式 disable 并写 reason

ts
// Stryker disable next-line EqualityOperator: <= 与 < 在 a===b 时等价,无法区分
return a < b ? b : a;
  • 确属等价变异体时,用注释指令带原因标记,保持团队可追溯。
  • 只有真正功能等价才该 disable——不是借口随手关掉杀不掉的变异体。

反模式(出题易错点)

  1. 全仓无差别跑 → 慢到没人愿意用、噪音淹没真问题。
  2. 把变异分数当硬 KPI 强制 100% → 逼出无意义测试、把等价变异体也硬测。
  3. 跳过覆盖率直接上变异测试 → 在大量 no coverage 上浪费算力,应先用覆盖率补齐「跑到」。
  4. 默认 break: null 还以为 CI 会卡 → 不设 break 永远不会 fail。
  5. 对 UI / 样板 / 生成代码跑变异 → 产出大量低价值 survived,噪音大。
  6. 把自己没写好的测试当等价变异体 disable → 掩盖真实测试缺陷。

下一步