TDD Workflow
用测试清单驱动的 Red-Green-Refactor 实操流程,以及 bugfix 与重构时的最小执行节奏。
#type / howto
#status / evergreen
#tech / dev / test
[!info] related notes
- 前置笔记: 测试驱动开发(TDD), 自测试代码(Self-Testing Code)
- 相关 MOC: 测试驱动开发 MOC, Testing MOC, 项目实践 MOC
TDD Workflow
目标
把需求切成一个个可以快速验证的小行为,按最小步伐反复执行:
- 写失败测试
- 写最小实现
- 在测试保护下重构
真正的关键不只是 Red-Green-Refactor 这三个词,而是每一轮都足够小、足够清楚、足够可验证。
步骤
0. 先写测试清单
不要一上来就写实现。先把要覆盖的行为外化成一个小清单,例如:
- 正常路径
- 边界值
- 异常输入
- 组合规则
- 已知 bug 回归
测试清单的作用,是避免你一边写代码一边丢需求,也避免 AI 或人类一步跳太大。
1. 进入 Red:只写下一个行为的失败测试
这个测试应该满足四个条件:
- 只代表一个明确意图
- 失败原因清楚
- 名字能表达业务行为
- 不要一口气覆盖多个场景
如果测试本身就很难命名,通常说明需求边界还没切清楚。
2. 进入 Green:只写最小实现
这一步的目标不是优雅,而是让刚才那个失败测试先变绿。
约束是:
- 不提前实现尚未被测试要求的逻辑
- 不顺手补未来分支
- 不为了让测试绿而改弱测试断言
3. 进入 Refactor:整理设计
当测试全绿后,再做这些动作:
- 消除重复
- 改善命名
- 抽清依赖
- 缩小职责
- 让结构更容易继续扩展
如果只做 Red-Green 不做 Refactor,TDD 很容易退化成“有测试保护的脏代码”。
4. 回到测试清单,继续下一轮
每次只拿一个最小行为进入下一轮,而不是一下铺开一组需求。
微循环越稳,反馈越准,设计也越不容易失控。
验证
一个健康的 TDD 节奏通常会这样验证:
- 先跑当前目标测试
- 再跑受影响的小范围测试集
- 最后再跑更完整的相关套件
这样能把反馈成本压低,也更容易定位是哪一轮改坏了行为。
修 bug 时怎么走
遇到 bug,优先按这个顺序:
- 先写一个能稳定复现问题的测试
- 确认它先失败
- 再改实现
- 让测试持续留在回归集里
这样修 bug 的结果不是“这次修好了”,而是“下次也不容易回来”。
常见问题
一次写太多
如果一轮里同时改测试、改实现、补未来逻辑、顺手重构,失败信号会变糊。
跳过 Refactor
只追求快速变绿,会让测试套件在保护行为的同时,继续包住一团越来越难维护的设计。
测试写得太贴实现
这会让你一重构就碎,最后对测试本身失去信任。
最短记忆方式
测试清单先行,单行为进入 Red,最小实现到 Green,全绿后再 Refactor。