L13. 测试驱动开发 (TDD) 入门:先画靶子再射箭
Vibe Coding 宣言:未经测试的代码是定时炸弹。与其被 Bug 炸死,不如先拆弹。
0. 为什么这一课至关重要? (Why It Matters)
- 颠覆直觉:正常人是“先写代码再测”,高手是“先写测试再写代码”。
- AI 的紧箍咒:如果你直接让 Claude 写代码,它会放飞自我。如果你先给它一个测试用例,它就必须写出能通过测试的代码。
- 安全感:当你看到绿色的
PASSED时,那种多巴胺分泌的感觉,比谈恋爱还爽。
1. 目标 (Goal)
理解 TDD (Test-Driven Development) 流程,学会用 pytest 编写测试,并让 Claude 根据测试写代码。
2. 核心概念/装备/指令 (The Core)
2.1 红-绿-重构 (Red-Green-Refactor)
TDD 的三步走:
- Red (红):写一个会报错的测试(因为功能还没写)。
- Green (绿):写最简单的代码,让测试通过。
- Refactor (重构):优化代码,保持测试通过。
2.2 Pytest (The Judge)
Python 界最好用的测试框架。
assert 1 + 1 == 2:断言。如果不对,程序就炸。pytest:运行所有测试。
3. 实战演练 (Action)
Step 1: 安装 pytest
bash
pip install pytestStep 2: 编写失败的测试 (Red)
我们要写一个“计算器”。新建 test_calc.py:
python
# test_calc.py
from calc import add
def test_add():
assert add(1, 2) == 3
assert add(-1, 1) == 0运行 pytest。 结果:报错 ModuleNotFoundError: No module named 'calc'。 点评:很好,这就是我们想要的红色。
Step 3: 让 Claude 写代码 (Green)
告诉 Claude:
markdown
# Context
我正在做 TDD。这是我的测试文件 `test_calc.py`:
[粘贴代码]
# Task
请创建 `calc.py`,实现 `add` 函数,使测试通过。Claude 会给你:
python
# calc.py
def add(a, b):
return a + b再次运行 pytest。 结果:2 passed in 0.01s (绿色)。
Step 4: 增加难度
修改 test_calc.py,加个除法:
python
def test_divide():
assert divide(10, 2) == 5
# 还可以测异常
with pytest.raises(ValueError):
divide(10, 0)让 Claude 继续实现。它必须处理除以零的异常。
4. 常见问题 (FAQ - Vibe Style)
Q: 写测试不浪费时间吗? A: 修 Bug 才浪费时间。 哪怕是简单的功能,写测试也只要 1 分钟。但如果上线后崩了,你修 Bug 可能要 1 小时。
Q: 所有的代码都要写测试吗? A: 核心逻辑必写。 UI 界面、一次性脚本可以不写。但涉及到钱、数据处理的核心算法,必须写。
Q: Claude 可以自己写测试吗? A: 可以! /test 指令就是干这个的。但最好的做法是:你写测试(定义需求),它写代码(实现需求)。 这样你才能控制它。
5. 验收标准 (Definition of Done)
- 安装好 pytest。
- 有一个
test_xxx.py文件,包含至少 2 个测试用例。 - 有一个实现文件,运行
pytest全部通过 (全绿)。
Next Mission: L14. 核心模块开发 (1):数据层的地基