test-drivenlisted
Install: claude install-skill Wade-DevCode/awesome-coding-skills-cn
# 测试驱动
## 何时用
- 实现一个新功能或新接口,还没有一行实现代码时。
- 修复 bug,想用测试把"错误行为"钉死,防止日后回归。
- 重构已有代码,需要一张安全网确认行为没有改变。
- 不确定某���边界条件下系统应该做什么,想用测试把期望行为写清楚再动手。
## 核心规则
### 1. 先写测试
**规则:** 在写任何实现代码之前,先写一个表达期望行为的测试。
**为什么:** AI 最常见的路线是"先把功能写出来,最后补测试"——但补出来的测试天然向实现靠拢,只覆盖 happy path,不会质疑假设。等实现已经存在,测试变成了橡皮图章:它测的是"代码现在怎么跑",而不是"代码应该怎么跑"。先写测试才能强迫自己想清楚"调用方视角的合约"。
**怎么做:**
- 从调用方视角出发:给什么输入,期望得到什么输出或副作用?
- 测试文件比实现文件先存在,`import` 指向尚不存在的模块也没关系,先写好断言。
- 一次只写一个测试用例,专注于当前最重要的行为。
---
### 2. 看它失败
**规则:** 写完测试后立即运行,确认测试因"功能未实现"而失败,而非因测试本身写错而失败。
**为什么:** AI 写完测试后经常直接跳到实现,跳过"看红"这一步。但如果测试从一开始就是绿的(比如断言条件写反了、`assert True` 之类),那整个 TDD 循环就是假的——你永远不知道这个测试有没有能力抓住真正的错误。一个从未失败过的测试,保护价值接近零。
**怎么做:**
- 运行测试,读错误信息,确认失败原因是 `ModuleNotFoundError`、`AttributeError` 或断言不等式,而非语法错误或导入错误(后者说明测试本身有 bug)。
- 如果测试意外通过了,停下来审查:是断言写错了,还是功能早已存在?搞清楚再继续。
- 把失败信息记下来,待会儿用于确认"绿"时对应的正是这个失败点。
---
### 3. 最小实现
**规则:** 只写刚好让当前测试通过的代码,不多写。
**为什么:** AI 一旦开始实现就容易"发散":顺手加错误处理、抽接口、加日志、考虑将来的扩展——测试还没绿,代码已经膨胀了一倍。最小实现原则把"让这一个测试通过"和"完善代码"拆成两个独立步骤,避免在不确定行为是否正确的时候就堆代码。
**怎么做:**
- 允许暂时写"硬编码返回值"——目的是让测试绿,再靠下一个测试逼迫你写真正的逻辑。
- 克制"顺手做"的冲动:看到相关代码有坏味道,记到 TODO,当前步骤只做让测试通过的最小改动。
- 实现完成后立即运行测试,不要先重构再���行。
---
### 4. 看它通过
**规则:** 运行测试,确认当前测试由红变绿,且原有测试仍然全绿。
**为什么:** AI 改完代码后会说"应该好了"而不真的跑。或者只运行新测试,没跑全量套件——导致刚写的实现破坏了��他已有功能,而这个问题要等 CI 才暴露。本地绿才算绿,口头绿不算绿。
**怎么做:**
- 运行**全量**测试套件,不只跑新写的测试文件。
- 若出现意外的新失败,先查清楚是新代码引入的回归还是测试本身的问题,再继续。
- 全绿之后才可以进入重构阶段("整理代码")。
---
### 5. 测行为,不测实现
**规则:** 测试只断言对外可观察的行为(返回值、副作用、抛出的异常),不断言内部实现细节(私有方法是否被调用、内部变量的值、调用次数等)。
**为什么:** AI 写测试时