[ PROMPT_NODE_25574 ]
test-driven-development
[ SKILL_DOCUMENTATION ]
# 测试驱动开发 (TDD)
## 概述
先写测试。观察它失败。编写最少量的代码使其通过。
**核心原则:** 如果你没有亲眼看到测试失败,你就不知道它是否测试了正确的东西。
**违反规则的字面意思就是违反规则的精神。**
## 何时使用
**总是使用:**
- 新功能
- Bug 修复
- 重构
- 行为变更
**例外情况(请咨询你的人类伙伴):**
- 一次性原型
- 生成的代码
- 配置文件
想“这次就跳过 TDD 吧”?停下。那是在找借口。
## 铁律
没有失败的测试,绝不编写生产代码
在测试之前写了代码?删掉它。从头开始。
**没有例外:**
- 不要把它留作“参考”
- 不要一边写测试一边“适配”它
- 不要看它
- 删除意味着彻底删除
完全基于测试重新实现。完毕。
## 红-绿-重构 (Red-Green-Refactor)
dot
digraph tdd_cycle {
rankdir=LR;
red [label="红 (RED)n编写失败测试", shape=box, style=filled, fillcolor="#ffcccc"];
verify_red [label="验证失败n是否正确", shape=diamond];
green [label="绿 (GREEN)n最少代码", shape=box, style=filled, fillcolor="#ccffcc"];
verify_green [label="验证通过n全部通过", shape=diamond];
refactor [label="重构 (REFACTOR)n清理代码", shape=box, style=filled, fillcolor="#ccccff"];
next [label="下一步", shape=ellipse];
red -> verify_red;
verify_red -> green [label="是"];
verify_red -> red [label="错误n失败"];
green -> verify_green;
verify_green -> refactor [label="是"];
verify_green -> green [label="否"];
refactor -> verify_green [label="保持n绿色"];
verify_green -> next;
next -> red;
}
### 红 (RED) - 编写失败测试
编写一个最简单的测试,展示应该发生什么。
typescript
test('重试失败操作 3 次', async () => {
let attempts = 0;
const operation = () => {
attempts++;
if (attempts < 3) throw new Error('fail');
return 'success';
};
const result = await retryOperation(operation);
expect(result).toBe('success');
expect(attempts).toBe(3);
});
命名清晰,测试真实行为,只做一件事
typescript
test('重试工作正常', async () => {
const mock = jest.fn()
.mockRejectedValueOnce(new Error())
.mockRejectedValueOnce(new Error())
.mockResolvedValueOnce('success');
await retryOperation(mock);
expect(mock).toHaveBeenCalledTimes(3);
});
命名模糊,测试的是 Mock 而非代码
**要求:**
- 单一行为
- 清晰