Skip to content

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 的三步走:

  1. Red (红):写一个会报错的测试(因为功能还没写)。
  2. Green (绿):写最简单的代码,让测试通过。
  3. Refactor (重构):优化代码,保持测试通过。

2.2 Pytest (The Judge)

Python 界最好用的测试框架。

  • assert 1 + 1 == 2:断言。如果不对,程序就炸。
  • pytest:运行所有测试。

3. 实战演练 (Action)

Step 1: 安装 pytest

bash
pip install pytest

Step 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)

  1. 安装好 pytest。
  2. 有一个 test_xxx.py 文件,包含至少 2 个测试用例。
  3. 有一个实现文件,运行 pytest 全部通过 (全绿)。

Next Mission: L14. 核心模块开发 (1):数据层的地基

基于 Claude Code 构建