Skip to content

L18. 单元测试与回归:守住你的阵地

Vibe Coding 宣言:Bug 是修不完的,但不让 Bug 复活是可以做到的。

0. 为什么这一课至关重要? (Why It Matters)

  • 打地鼠游戏:修了一个 Bug A,结果导致了 Bug B。这种绝望感,只有没写测试的人才懂。
  • 回归测试 (Regression):每次修改代码后,把所有测试跑一遍,确保旧功能没挂。
  • 覆盖率 (Coverage):你知道你的代码有多少行是被测试过的吗?

1. 目标 (Goal)

学会使用 pytest 进行全面的单元测试,并生成 Coverage Report (覆盖率报告)。

2. 核心概念/装备/指令 (The Core)

2.1 单元测试 (The Unit)

测一个函数,不管其他的。

  • Mocking: 模拟外部依赖(比如数据库、API)。
  • Fixture: 准备测试数据。

2.2 覆盖率 (The Map)

  • pytest-cov: 一个插件,告诉你测试跑到了哪些代码行。
  • 100% 覆盖率:是理想,不是必须。核心逻辑做到 90% 就很好了。

3. 实战演练 (Action)

Step 1: 安装 pytest-cov

bash
pip install pytest-cov

Step 2: 编写 Mock 测试

假设你要测“发邮件”函数,但不想真的发邮件。

python
# test_email.py
from unittest.mock import patch
from notification import send_email

def test_send_email():
    with patch('smtplib.SMTP') as mock_smtp:
        send_email('test@example.com', 'Hello')
        # 验证 SMTP 是否被调用了
        assert mock_smtp.called

Step 3: 让 Claude 补全测试

markdown
# Context
我有以下文件 `service.py` [粘贴代码]。

# Task
请为这个文件编写全面的单元测试。
覆盖所有分支(if/else)。
使用 Mock 模拟数据库连接。

Step 4: 查看覆盖率

运行:

bash
pytest --cov=src tests/

你会看到一个表格,显示每个文件的覆盖率百分比。

4. 常见问题 (FAQ - Vibe Style)

Q: 必须要用 Mock 吗? A: 涉及外部系统必须用。 你不想每次跑测试都在数据库里插一条垃圾数据吧?也不想每次都调一次收费 API 吧?

Q: 覆盖率多少合适? A: 二八法则。 80% 的 Bug 藏在 20% 的复杂逻辑里。把那 20% 测透。剩下的 Getter/Setter 没必要测。

Q: 测试代码比业务代码还多? A: 正常的。 优秀的开源项目,测试代码通常是业务代码的 2-3 倍。

5. 验收标准 (Definition of Done)

  1. 运行 pytest 全部通过。
  2. 运行 pytest --cov,核心模块覆盖率超过 80%。
  3. 没有直接调用外部 API(全部 Mock 了)。

Next Mission: L19. 重构与优化:让代码更性感

基于 Claude Code 构建