本文内容
测试驱动开发能证明什么,又不能证明什么
测试驱动开发(TDD)是一种通过短反馈周期开发软件的方法。开发者先为下一个行为编写测试,确认测试失败,再实现刚好足以让测试通过的代码,最后在测试套件保持通过的情况下重构。这个方法可以尽早暴露假设和预期行为,但不能让软件没有缺陷,也不能取代生产系统所需的其他控制措施。
正在打造软件产品?
预约免费咨询TDD 周期真正承诺的内容
Martin Fowler 对核心循环的描述是:为下一项功能编写测试,编写功能代码直到测试通过,然后把代码重构成更清晰的结构。团队通常把它概括为红灯、绿灯、重构。测试应当先因一个有意义的原因失败,否则,测试通过可能只说明它从未真正执行预期行为。
TDD 是一种开发纪律,不是覆盖率保证。开发者可能遗漏重要场景、断言错误结果、通过模拟绕开高风险集成,或者完美保留一项有缺陷的需求。更可靠的表述是:当测试套件稳定运行时,由有意义测试表达的行为可以获得快速的回归反馈。
著名的飞蛾并不是“bug”一词的起源
1947 年,参与哈佛 Mark II 计算机工作的工程师在一个组件中发现一只飞蛾,并将它贴在日志本中,旁边写着“first actual case of bug being found”。Grace Hopper 是与 Mark II 团队共同工作的人之一。这件事推动了计算机领域对“bug”和“debug”这两个词的使用,但并没有创造“bug”这个词。现存日志也无法确定是 Hopper 本人记录的。

Mark II 飞蛾事件记录于 1947 年。
TDD 可以在哪些方面提供帮助
TDD 在团队可以用小而确定的示例表达行为时尤其有用。它可以帮助澄清接口、暴露不合理的耦合、支持安全重构,并让已修复的行为持续接受自动检查。它也为代码审查提供了具体材料:审查者可以比较声明的行为、实际实现,以及测试没有覆盖的边界。
经济结果取决于具体情境。TDD 需要设计与维护投入,脆弱或缓慢的测试套件本身也可能成为交付成本。它能否节省资金,取决于缺陷风险、变更频率、系统寿命、测试范围、反馈速度和故障成本。负责任的商业评估应衡量逃逸缺陷、交付周期、不稳定测试比例、测试时长、维护投入和恢复结果,而不是承诺普遍适用的节省幅度。

"用测试让重要假设成为可执行规范,再验证这些测试无法覆盖的风险。"
为什么测试通过不能证明正确性
测试套件评估的是选定输入与预期结果,本身无法证明缺陷不存在。全部测试通过,仍可能遗漏并发故障、异常外部数据、依赖项行为、授权漏洞、生产配置问题或错误的业务规则。覆盖率百分比也需要结合语境解读:某一行代码被执行,并不表示所有重要状态转换或不变量都经过了测试。
应根据风险选择技术。单元测试适合验证局部行为,契约测试与集成测试覆盖组件之间的边界,基于属性的测试和模糊测试可以探索团队未手动列出的输入,静态分析则能在不执行程序的情况下发现某些类别的实现弱点。代码审查、威胁建模、渗透测试、运行监控和事故演练分别覆盖系统的不同部分。
智能合约有什么不同?
智能合约可能控制高价值资产、公开调用入口、与外部合约组合,并按特定协议规则运行。这些特点会提高授权、记账、预言机、升级或经济设计错误的代价,但不会让 TDD 成为完整的安全方法。
对于 EVM 系统,生产验证计划可以把基于示例的单元测试与不变量或属性测试、模糊测试、静态分析、分叉网络集成测试、访问控制审查、编译器与依赖项检查,以及针对业务逻辑和经济攻击的人工评估结合起来。前端、API、钱包、索引器、数据库和运营控制都需要各自的测试范围。审计能提供额外证据,但不能保证系统不存在可利用的漏洞。
测试投入和缺陷成本因系统而异;这张图表达的是概念,不是实测曲线。
实用审查清单
- 行为:团队能否在实现前说明重要验收标准与不变量?
- 故障模式:哪些异常输入、不可用依赖项、权限错误、重试和部分失败需要关注?
- 测试边界:哪些部分是真实的、模拟的、仿真的,或者明确不在测试范围内?
- 反馈:测试套件能否足够快速、稳定地运行,从而影响日常决策?
- 安全:哪些风险需要 TDD 以外的静态分析、模糊测试、审查、审计、监控或运营控制?
- 证据:哪些发布门槛和生产信号能表明系统行为可接受?
如何评估工程合作伙伴
不要只用“是否始终采用 TDD”这样的单一理念问题筛选团队,而应要求对方解释针对具体风险的测试策略。可信的回答应说明哪些内容会做单元测试,哪些内容需要集成或端到端证据,如何表示外部系统,怎样处理不稳定测试,哪些安全技术用于补充测试套件,以及什么证据会阻止发布。
没有自动化测试的项目不一定必然失败,拥有庞大测试套件的项目也不一定成功。关键在于风险与反馈。测试那些一旦失败就会产生重要影响的行为,保持测试套件可信,并为测试无法证明的部分采用互补控制措施。
资料来源
最终思考
TDD 可以把预期行为转化为快速且可重复的反馈。它的价值来自选择有意义的测试并保持测试套件可靠。TDD 无法证明软件正确或安全,因此生产团队应根据系统的实际风险,结合适当的测试、审查、安全和运营控制。