测试金字塔的底两层:单元测试测单个零件(一个函数、一个类),集成测试测零件装起来后接缝处会不会漏。核心思想:bug 越晚发现,修理越贵——单元测试是成本最低的把关点。
一、单元测试:给每个零件一个考官
单元=可独立运行的最小代码块(一个函数、一个类的方法)。单元测试做的事:喂已知输入,断言输出符合预期。
def add(a, b):
return a + b
def test_add_normal():
assert add(2, 3) == 5
def test_add_negative():
assert add(-1, 1) == 0
def test_add_float():
assert abs(add(0.1, 0.2) - 0.3) < 1e-9 # 浮点比较用误差范围(3-7 的教训)
写测试的三原则:
- 一个测试只测一件事——挂了能立刻定位。
- 可重复——任何时候跑结果都一样(不依赖网络、时间、随机数)。
- 先写测试再修 bug——修 bug 前先写一个【能复现 bug 的测试】,修好它变绿,这个 bug 永远不会再悄悄回来。
二、集成测试:接缝处最易漏水
零件全对,组装起来照样可能出错——接口约定不一致、数据格式错位、顺序假设不同,都是接缝病。集成测试把两个以上模块连起来跑:数据库读写、函数互相调用、模块间传数据。
教材强调集成有【自底向上】【自顶向下】【大爆炸】等策略:小模块先测好再逐层拼(自底向上)风险最可控;一把梭全拼一起再测(大爆炸)出了错根本不知道查谁。
三、测试金字塔
/验收/系统\ 少而慢而贵(端到端)
/ 集成测试 \ 中等数量,测接缝
/ 单元测试 \ 多而快而便宜(地基)
越往下越多:单元测试又快又便宜,铺到几百上千个都行;端到端测试慢且脆,只留关键路径。这个形状是成本结构决定的。
四、Python 的测试工具:pytest
Python 事实标准是 pytest(2026 年 6 月已到 9.1.1,要求 Python 3.10+,生态 1300+ 插件):不用类不用 self.assert*,写普通 assert 就行,失败时自动把中间值打印给你看。命名约定:文件 test_*.py、函数 test_*,命令行敲 pytest 自动发现全部。
五、动手 Demo:为 5-2 的 find_max_value 补上它欠的测试
def find_max_value(numbers):
if not numbers:
return None
max_value = numbers[0] # 修好初值雷:从第一个元素起
for number in numbers:
if number > max_value:
max_value = number
return max_value
# —— 以下放 test_xxx.py 里,跑 pytest 即自动发现 ——
def test_max_normal():
assert find_max_value([12, 31, 25, 8]) == 31
def test_max_negative():
assert find_max_value([-5, -2, -9]) == -2 # 5-2 的初值雷在此现形
def test_max_empty():
assert find_max_value([]) is None
def test_max_single():
assert find_max_value([7]) == 7
print(find_max_value([12, 31, 25, 8]))
print(find_max_value([-5, -2, -9]))
print(find_max_value([]))
沙箱实跑输出:
31
-2
None
看到什么算成功:三行输出全对——特别是负数列表返回 -2 而不是 5-2 版本的错误 0。
读结果:四个测试正好对应正常/边界/空输入/单元素四类——写测试逼着你把【没想过的情况】一个个列出来。测试不是验证代码对,是搜索代码错。
六、30 秒实验
把 max_value = numbers[0] 改回 max_value = 0,再跑 print(find_max_value([-5, -2, -9]))——输出 0。如果 pytest 在场,test_max_negative 立刻变红。改坏任何东西,测试网会第一时间尖叫。
七、常见误区
| 误区 | 真相 |
|---|---|
| 测试是测试员的事 | 单元测试是开发者自己的武器,写代码的人最了解接缝 |
| 测试通过=没有 bug | 测试只能证明【测过的路径】对;未测的分支照样藏雷(5-5 覆盖率) |
| 没时间写测试 | bug 逃到线上后再来算账,成本是单元测试阶段的十倍起 |
自测三问(点击展开)
1. **单元和集成测试的分界是什么?** 答:单元测单个零件独立运行,集成测多零件连接后的接缝与交互。 2. **浮点数断言为什么用误差范围?** 答:IEEE 754 是近似存储,`0.1+0.2 != 0.3`,直接 `==` 会误报(3-7 的老朋友)。 3. **修 bug 前先写什么?** 答:先写一个能复现 bug 的失败测试,修好让它们变绿——防复发。- ☐ 5-3 学习完成
相关笔记
- 黑盒与白盒、覆盖率 —— 测试得够不够准
- 整数与浮点数 —— 浮点断言用误差范围的出处
- ⌨️ 编程原理 · 索引 —— 全课路线图