目标
弱测试比没有测试更糟:它提供没有保护的信心。在评审中追问断言强度、隔离性与失败可诊断性——“行为坏了它会不会挂?挂了能不能指出坏在哪?”——测试套件才能从仪式变成仪器。清单条目要从真实失败案例里长出来,每条都注明它防的是哪类事故。
步骤要点
- 从真实失败写清单:把实际上线过的坏测试归纳成条目——空壳断言、顺序依赖、sleep 等待、共享夹具、忽略清理,每条注明防的事故类别。
- 评审断言强度:核验每条测试断言的是促成它存在的那个行为——状态结果优于调用序列、具体值优于真值判断、错误细节优于 catch-all。
- 评审隔离与确定性:查隐藏共享状态、墙上时钟依赖、无种子随机与网络外呼,要求种子与替身。
- 要求失败可诊断:评估失败信息能教给值班的人什么——got 与 want 的差异能否直指原因。
- 跟踪反模式趋势:按类别统计清单驳回数,把培训对准最高频的惯犯。
排错提示
expect(result).toBeTruthy() 式断言能过今天却对明天撒谎,评审要换成具体值断言;测试挂了只报 assertion failed 让人凌晨翻夹具,断言要写成你想收到的那种失败信息;驳回类别月月相同说明标准没内化,把最高频反模式做成 lint 规则自动拦截。
适用边界
评审标准提升测试下限而非上限,探索性测试设计仍依赖作者功力;清单条目会随框架演进过时,需定期从新失败中回填。
代码示例
checklist (item -> failure it prevents):
A1 asserts outcome state, not call log -> refactor-brittle
A2 specific values, not truthiness -> false green
A3 error case asserts message/type -> swallowed bugs
I1 no shared mutable fixtures -> order flakes
I2 no wall-clock/sleep waits -> timing flakes
I3 randomness seeded + logged -> unreproducible
D1 failure message shows got vs want -> 2am debugging
review catch example:
expect(result).toBeTruthy() <- A2: rejects
-> expect(result.totalCents).toBe(850)