30 秒看懂
Dave Farley 讨论无意义断言、过多设置、巨型测试、过度模拟和检查私有内部细节的测试。他认为聚焦的测试与更好的关注点分离可以把测试困难转化为设计反馈。
- 1骗子没有有用断言的通过测试会制造虚假的信心。
- 2过多设置复杂设置可能暴露难处理的依赖。
- 3巨型测试大型测试可能掩盖究竟哪种行为失败。
- 4模拟至空把一切都模拟掉可能导致没有真正行为被测试。
- 5检查器与私有内部细节绑定的断言可能使测试脆弱。
要点建议
- 没有有用断言的通过测试会制造虚假的信心。
- 复杂设置可能暴露难处理的依赖。
- 大型测试可能掩盖究竟哪种行为失败。
- 把一切都模拟掉可能导致没有真正行为被测试。
- 与私有内部细节绑定的断言可能使测试脆弱。
按章节阅读整理后的全文
测试作为设计反馈
Farley 介绍反馈循环的目的。
Dave Farley 认为测试驱动开发中的困难可以提示软件设计问题。在这场 2021 年的讲解中,他分析五种测试反模式,并提出让反馈更有用的方法。
在 Farley 看来,TDD 的价值不只是覆盖率数字:在短反馈循环中编写测试和代码,可以暴露耦合、关注点分离不佳和接口难用等问题。这些信号仍需结合具体情况判断。
无意义测试与设置
前两种模式暴露薄弱断言和难处理的依赖。
第一种反模式“骗子”是通过了却没有作出有意义断言的测试。他回忆一个覆盖率目标促使人们编写了执行代码却没有检查有用行为的测试。
他建议删除或改进无意义的测试,并在实现行为前观察新测试是否因预期原因失败。测试失败是有用证据,但仅凭失败并不能保证测试正确。
“过多设置”指准备测试需要大量工作。Farley 将其视为检查依赖和关注点分离的信号,而不是立刻接受脆弱的设置。
他展示一个为了检查 URL 字符串而启动整个 Jenkins 环境的测试。对这个特定行为,更小的单元级检查可能更快、更清晰;当交互本身重要时,更广泛的集成测试仍可能合适。
大型测试与模拟
他讨论意图不清和过度使用测试替身。
“巨型测试”是很长、包含许多断言且意图不清的测试。Farley 说,当互不相关的行为被捆绑在同一个用例里,失败可能很难诊断。
他倾向于将这种用例拆成聚焦的测试,并建议把每个测试一个断言作为经验法则。当多个相关断言共同描述一个完整行为时,它们也可能是合理的。
“模拟至空”依赖了过多 mock 或 stub,以至于几乎没有运行真实生产行为。在他的例子中,汽车和发动机都被模拟,测试的是配置好的替身,而非真实实现。
他建议重新审视设计,关注软件必须提供的行为。测试替身在边界处可能有用,但不应替代测试本来要验证的行为。
封装与行为
最后一种模式涉及与内部细节耦合的测试。
“检查器”通过破坏封装来断言私有实现细节。Farley 警告,与内部实现紧密耦合的测试可能在无害重构后失败,即使外部可观察行为仍然正确。
他展示了一个似乎只为测试加入的方法,追问更好的抽象或依赖边界能否让测试观察行为而不暴露私有状态。这是设计问题,不是禁止所有测试专用检测手段。
贯穿五种反模式的主题是把测试阻力当作反馈:简化设置、明确行为、改善分离,并避免把覆盖率本身当作目标。
同频道的其他文章
39:12EN → 简体中文
22:33EN → 简体中文
34:11EN → 简体中文
28:15EN → 简体中文
46:36EN → 简体中文
28:23EN → 简体中文