⌨️ 第五章 从设计到测试
📄 本篇摘要

测试金字塔的底两层:单元测试测单个零件(一个函数、一个类),集成测试测零件装起来后接缝处会不会漏。核心思想: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 的教训)

写测试的三原则:

  1. 一个测试只测一件事——挂了能立刻定位。
  2. 可重复——任何时候跑结果都一样(不依赖网络、时间、随机数)。
  3. 先写测试再修 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 的失败测试,修好让它们变绿——防复发。

相关笔记