AI 让代码生成速度大幅提高,一个模块可能几十分钟就能完成,单元测试也很容易做到表面上的 100% 通过。但问题在于:这些测试有时根本没有验证真正的需求,只是在证明刚写出来的代码符合它自己生成的用例。
什么是 TDD
TDD 即测试驱动开发,核心是用一个很小的循环验证模块或流程。这里涉及两个状态:
- 红测:在实现需求之前编写、按预期必然失败的测试。
- 绿测:完成需求后再次运行同一测试,成功通过即转为绿色。
TDD 真正重要的产物不只是测试代码,而是写测试时体现出的设计。如果一段逻辑能写出简洁、明确的测试,通常说明它的边界清晰、职责单一;如果测试难以编写,设计本身可能就需要重新检查。
为什么 AI 开发更需要红测
1. AI 生成代码的不可靠性
人工编写代码速度较慢,开发者在实现过程中通常会自然地进行审查。Agent 可以在短时间生成大量代码,却未必具备同等强度的自我审查;如果它把自认为正确的实现直接交付,问题可能进入线上。
2. 避免“假绿”
如果先让 AI 写实现,再让同一个 AI 根据实现补单元测试,它已经知道结果,很容易为了现有代码构造能够通过的用例。这相当于同时担任运动员和裁判。
Agent 可以验证代码是否符合某个测试用例,却无法仅凭自身判断团队是否正在实现正确的需求。因此,测试必须在实现之前确立,而不能只在代码完成后补写。
实际执行流程
- 在计划阶段先写测试,并确认它在当前实现下失败。这个失败状态就是红测,用来证明现有代码确实尚未满足需求或尚未修复缺陷。
- 如果预期的红测一开始就通过,应立即停止写代码,重新检查需求、测试条件或问题判断,因为基线可能已经错了。
- 完成需求或修复缺陷后,重新运行完全相同的测试。
- 如果测试由红转绿,说明修改确实影响了被验证的根本原因;如果仍然是红色,则说明实现还有问题。
绿测只表示最终结果,红测记录起始状态。只有把两者结合起来,才能证明需求或缺陷经历了明确的状态流转。
单元测试的长期作用与边界
不必盲目追求单元测试数量或覆盖率。测试的价值之一就是在未来主动报错:今天编写的测试记录了当前 Agent 对系统行为的理解,将来出现失败,意味着旧实现、旧假设与新改动之间发生了冲突,需要重新审查。
同时,测试类型需要根据问题选择。原帖特别指出了几个尚需进一步判断的边界:
- 选择了错误的 JDK,却把环境问题误当成业务红测;
- 哪些逻辑适合纯单元测试,哪些必须连接数据库做自动化测试;
- 前后端协作中,接口报错可能由前端调用方式引起,单独测试后端未必能覆盖。
这套方法的重点不是让 AI 多写测试,而是先用失败测试固定需求和缺陷,再让实现把同一个测试推到成功状态。
原作者:woji_666(这里是沃基)
原帖:https://linux.do/t/topic/2925318