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

两只眼睛看代码:黑盒测试不看内部、只喂输入验输出;白盒测试打开盖子、按内部路径设计用例。覆盖率回答【白盒测到什么程度了】——行覆盖、分支覆盖,数字越高没测到的死角越少。但要记牢:覆盖率是必要条件,不是充分条件。

📝 关系

上一节:系统测试与验收测试 | 下一节:等价划分与边值分析

一、黑盒测试:只看输入和输出

把程序当一台不透明的机器:不关心里面怎么写的,只关心给什么输入、该出什么输出。好处:

短板:不知道内部结构,就不知道哪些路径漏测了——补上白盒这只眼。

二、白盒测试:沿着路径走

打开盖子,看着代码设计用例:每个 if 的两个方向都走到了吗?循环的 0 次、1 次、多次都试了吗?白盒用例直指内部分支,专抓黑盒够不到的死路。

教材里常见的标准:

三、覆盖率:白盒的刻度尺

覆盖率=(已执行的元素数)÷(元素总数)。行覆盖 80% 意味着还有两成代码从没跑过——从没跑过的代码,就是从未验证过的代码。工具自动统计(Python 的 pytest 配 coverage 插件一行命令)。

但是——100% 覆盖率不等于没有 bug:覆盖率只说明【代码被执行过】,不说明【断言写对了】。一个 assert True 就能把覆盖率刷满而什么都没测。覆盖率用来找【漏】,不能用来证【对】。

四、动手 Demo:一行代码测出覆盖率的含义

def discount(price, is_vip):
    """会员或满 100 打八折,否则原价"""
    if is_vip or price >= 100:
        return price * 0.8
    return price

# 黑盒视角:随便挑几个典型输入
print(discount(200, True))    # 160.0
print(discount(50, False))    # 50

# 白盒视角:分支覆盖——if 的两个方向都要走到
# 方向 1(进打折分支):discount(200, True)
# 方向 2(不进)      :discount(50, False)
# 两行就 100% 行覆盖了?——再看 or 的短路:
print(discount(200, False))   # 160.0  靠价格条件进
print(discount(30, True))     # 24.0   靠会员条件进

沙箱实跑输出:

160.0
50
160.0
24.0

看到什么算成功:四个输出与注释一致。

读结果:前两个用例已达 100% 行覆盖,但 is_vip or price >= 100 这个复合条件的每种取值来源没被单独验证过——后两个用例补上。行覆盖是地板,分支覆盖才是及格线。

五、30 秒实验

把 if is_vip or price >= 100 手滑写成 if is_vip and price >= 100,重跑四个用例——第 3 个(200 元非会员)立刻输出 200 而非 160,bug 被抓。这正是一个行覆盖 100% 却能被分支测试抓住的 bug。

六、常见误区

误区 真相
覆盖率 100% 就稳了 覆盖率只统计【跑过】,不管【断言对不对】
黑盒和白盒二选一 互补:黑盒保视角、白盒保路径;两个都要
覆盖率是 KPI 越高越好 刷指标的测试比没测试更危险——虚假安全感
自测三问(点击展开) 1. **黑盒和白盒的分界是什么?** 答:黑盒不看内部只验输入输出,白盒看着内部代码按路径设计用例。 2. **语句覆盖和分支覆盖谁强?** 答:分支覆盖强——每个判断的真假都走到,语句覆盖可能只走了真方向。 3. **为什么 100% 覆盖率不等于没 bug?** 答:覆盖率只记录代码被执行,断言写错或缺失时照样测不出来。

相关笔记