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-covStep 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.calledStep 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)
- 运行
pytest全部通过。 - 运行
pytest --cov,核心模块覆盖率超过 80%。 - 没有直接调用外部 API(全部 Mock 了)。
Next Mission: L19. 重构与优化:让代码更性感