一、白盒测试核心概述
1.1 定义
白盒测试又称结构测试、透明盒测试、逻辑驱动测试,是一种基于软件程序内部代码逻辑、程序结构的测试方法。
一句话理解:把程序当成一个"透明的玻璃盒",测试人员能看到里面的每一条语句、每一个分支、每一个循环,然后设计用例把该跑的逻辑都跑一遍。
测试人员完全知晓源代码、执行逻辑、分支条件、循环结构、数据流走向,不再关注程序的业务输入输出结果,而是聚焦代码是否全部执行、分支是否全覆盖、逻辑路径是否无遗漏。它属于静态+动态结合的单元测试核心手段,多用于开发自测、单元测试阶段。
1.2 为什么需要白盒测试?
黑盒测试只能验证"输入→输出"是否正确,但无法发现:
- 某条
if分支永远进不去(死代码) - 某个
else逻辑写反了但恰好输出正确 - 循环边界少执行一次
白盒测试的核心价值:用覆盖率量化"代码被验证了多少"。
1.3 核心特点
| 特点 | 说明 |
|---|---|
| 可见性 | 完全透明代码内部结构,穿透业务表层,检测底层逻辑缺陷 |
| 针对性强 | 可精准发现代码死循环、无效语句、逻辑冲突、分支遗漏问题 |
| 覆盖率导向 | 所有测试方法的核心目标是提升代码逻辑覆盖率 |
| 局限性 | 无法检测需求缺失、业务逻辑错误,仅保障代码执行正确性 |
1.4 适用场景
单元测试、代码重构回归测试、核心算法逻辑测试、软考软件设计师/评测师必考考点。
二、实战代码与逻辑拆解
2.1 被测代码
defrisk_check(user_level,amount,is_blacklist,coupon_count):""" 订单风控判定 user_level : 用户等级,0-普通 1-VIP amount : 订单金额 is_blacklist: 是否黑名单,True/False coupon_count: 优惠券张数 返回 risk 风险等级:0-低 1-中 2-高 3-拒绝 """risk=0# 判定D1:复合条件(C1 and C2)ifuser_level==1andamount>=1000:risk=1# 判定D2:复合条件(C3 or C4)ifis_blacklistoramount>5000:risk=2# 判定D3:嵌套判定,外层含 C5,内层含 C6ifcoupon_count>0:ifamount<100:risk=3returnrisk2.2 逻辑拆解(全文共用,务必记牢)
独立条件(共6个)
| 编号 | 条件 | 所在判定 |
|---|---|---|
| C1 | user_level == 1 | D1 |
| C2 | amount >= 1000 | D1 |
| C3 | is_blacklist == True | D2 |
| C4 | amount > 5000 | D2 |
| C5 | coupon_count > 0 | D3外层 |
| C6 | amount < 100 | D3内层 |
判定(共3个,4层)
| 编号 | 判定表达式 | 类型 |
|---|---|---|
| D1 | C1 and C2 | 复合条件判定 |
| D2 | C3 or C4 | 复合条件判定 |
| D3外层 | C5 | 单条件判定 |
| D3内层 | C6 | 单条件判定 |
关键提醒:D3 是嵌套判定,外层 C5 为假时,内层 C6根本不执行。这一点会让"条件覆盖"和"路径覆盖"的用例数产生本质差异。
三、六大核心方法(同一段代码,六组不同用例)
覆盖强度由弱到强依次递增:
语句覆盖 < 判定覆盖 < 条件覆盖 < 判定-条件覆盖 < 条件组合覆盖 < 路径覆盖
3.1 语句覆盖(最弱覆盖)
核心原理:每条可执行语句至少执行一次。
推导:要让risk=1、risk=2、risk=3都执行,一条用例即可。
| 用例 | user_level | amount | is_blacklist | coupon_count | 最终risk |
|---|---|---|---|---|---|
| 1 | 1 | 6000 | True | 1 | 3 |
验证:D1真→risk=1✓;D2真→risk=2✓;D3外层真→内层执行→risk=3✓。
缺陷:risk=3被执行但内层判定为假,语句覆盖无法发现"内层恒假"的逻辑错误。
优缺点:✅ 用例最少;❌ 漏测率极高。
3.2 判定覆盖(分支覆盖)
核心原理:每个判定的真、假分支至少执行一次。
分支清单:D1有T1/F1,D2有T2/F2,D3外层有T3/F3,D3内层有T4/F4,共8个。
| 用例 | user_level | amount | is_blacklist | coupon_count | 覆盖分支 |
|---|---|---|---|---|---|
| 1 | 0 | 500 | False | 0 | F1、F2、F3 |
| 2 | 1 | 2000 | False | 0 | T1、F2、F3 |
| 3 | 0 | 6000 | True | 1 | F1、T2、T3、F4 |
| 4 | 0 | 50 | False | 1 | F1、F2、T3、T4 |
覆盖验证:T1✓ F1✓ T2✓ F2✓ T3✓ F3✓ T4✓ F4✓
缺陷:看不到条件细节。D2是C3 or C4,用例3用C3真覆盖T2,但C4真假从未单独验证。
优缺点:✅ 覆盖所有分支;❌ 无法覆盖条件组合。
3.3 条件覆盖
核心原理:每个独立条件的真、假至少执行一次。
6个条件需覆盖12种状态。难点:C6在内层,必须先让C5真才能执行到。
| 用例 | user_level | amount | is_blacklist | coupon_count | C1 | C2 | C3 | C4 | C5 | C6 |
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 0 | 500 | False | 0 | 假 | 假 | 假 | 假 | 假 | — |
| 2 | 1 | 2000 | False | 0 | 真 | 真 | 假 | 假 | 假 | — |
| 3 | 0 | 6000 | True | 1 | 假 | 真 | 真 | 真 | 真 | 假 |
| 4 | 0 | 50 | False | 1 | 假 | 假 | 假 | 假 | 真 | 真 |
覆盖验证:C1真假✓ C2真假✓ C3真假✓ C4真假✓ C5真假✓ C6真假✓
关键陷阱:条件覆盖≠判定覆盖。可能"条件全取真假,但某判定分支一次没走"。
优缺点:✅ 覆盖最小单元;❌ 不保证判定分支全覆盖。
3.4 判定-条件覆盖(重点)
核心原理:同一组用例同时满足判定覆盖+条件覆盖。
| 用例 | user_level | amount | is_blacklist | coupon_count | 覆盖判定分支 | 覆盖条件 |
|---|---|---|---|---|---|---|
| 1 | 0 | 500 | False | 0 | F1、F2、F3 | C1假、C2假、C3假、C4假、C5假 |
| 2 | 1 | 2000 | False | 0 | T1、F2、F3 | C1真、C2真、C3假、C4假、C5假 |
| 3 | 0 | 6000 | True | 1 | F1、T2、T3、F4 | C1假、C2真、C3真、C4真、C5真、C6假 |
| 4 | 0 | 50 | False | 1 | F1、F2、T3、T4 | C1假、C2假、C3假、C4假、C5真、C6真 |
验证:判定分支8个全覆盖✓;条件状态12种全覆盖✓
注意:不保证条件组合全覆盖。D1中C1真C2假未覆盖。
优缺点:✅ 兼顾判定和条件;❌ 无法覆盖组合逻辑。
3.5 条件组合覆盖(高覆盖)
核心原理:每个判定内部,所有条件的真假组合全覆盖。
组合数:D1含2条件→4种;D2含2条件→4种;D3外层→2种;D3内层→2种(要求C5真)。
| 用例 | user_level | amount | is_blacklist | coupon_count | 覆盖组合 |
|---|---|---|---|---|---|
| 1 | 1 | 2000 | True | 0 | D1:C1T+C2T;D2:C3T+C4F;D3外层:C5F |
| 2 | 1 | 500 | True | 1 | D1:C1T+C2F;D2:C3T+C4F;D3外层:C5T;D3内层:C6F |
| 3 | 0 | 2000 | False | 1 | D1:C1F+C2T;D2:C3F+C4F;D3外层:C5T;D3内层:C6F |
| 4 | 0 | 500 | False | 0 | D1:C1F+C2F;D2:C3F+C4F;D3外层:C5F |
| 5 | 0 | 6000 | False | 1 | D1:C1F+C2T;D2:C3F+C4T;D3外层:C5T;D3内层:C6F |
| 6 | 0 | 50 | False | 1 | D2:C3F+C4F;D3外层:C5T;D3内层:C6T |
| 7 | 0 | 6000 | True | 0 | D2:C3T+C4T;D3外层:C5F |
组合核对:
- D1:4/4✓
- D2:C3T+C4T✓(7)C3T+C4F✓(1、2)C3F+C4T✓(5)C3F+C4F✓(3、4、6)→4/4
- D3外层:2/2✓
- D3内层:2/2✓
注意:不保证路径覆盖。"D1真、D2假、D3外层真、内层真"未出现。
优缺点:✅ 覆盖所有条件组合;❌ 用例随条件数指数增长。
3.6 路径覆盖(最强覆盖)
核心原理:覆盖所有完整执行路径。
路径拆解(共5条):D3内层只有外层为真才执行,路径数不是2×2×2×2=16。
| 路径 | D1 | D2 | D3外层 | D3内层 | 最终risk |
|---|---|---|---|---|---|
| P1 | 假 | 假 | 假 | — | 0 |
| P2 | 真 | 假 | 假 | — | 1 |
| P3 | 假 | 真 | 假 | — | 2 |
| P4 | 假 | 假 | 真 | 假 | 0 |
| P5 | 假 | 假 | 真 | 真 | 3 |
| 用例 | user_level | amount | is_blacklist | coupon_count | 路径 | 最终risk |
|---|---|---|---|---|---|---|
| 1 | 0 | 500 | False | 0 | P1 | 0 |
| 2 | 1 | 2000 | False | 0 | P2 | 1 |
| 3 | 0 | 6000 | True | 0 | P3 | 2 |
| 4 | 0 | 500 | False | 1 | P4 | 0 |
| 5 | 0 | 50 | False | 1 | P5 | 3 |
验证:5条路径100%覆盖。
优缺点
- ✅ 覆盖率最高,可发现路径死区
- ❌ 路径数指数级暴涨;无法检测需求缺失
四、六大方法对比速查表(必背)
| 方法 | 覆盖对象 | 用例数 | 强度 | 软考频率 |
|---|---|---|---|---|
| 语句覆盖 | 可执行语句 | 1 | ★ | 高 |
| 判定覆盖 | 判定真假分支 | 4 | ★★ | 高 |
| 条件覆盖 | 独立条件真假 | 4 | ★★★ | 高 |
| 判定-条件覆盖 | 判定+条件 | 4 | ★★★★ | 高 |
| 条件组合覆盖 | 条件真假组合 | 7 | ★★★★★ | 中 |
| 路径覆盖 | 完整执行路径 | 5 | ★★★★★★ | 高 |
强度排序口诀:语判条,判条组路
易错点
- 条件覆盖不包含判定覆盖
- 判定-条件覆盖不包含条件组合覆盖
- 条件组合覆盖不包含路径覆盖
- 用例数多少≠强度高低:路径覆盖用例数(5)少于条件组合覆盖(7),但强度更高
五、课后小练(含标准答案)
5.1 题目题干
现有如下 Python 代码,实现一个登录安全审计函数:
deflogin_audit(fail_count,captcha_ok,account_locked,ip_abnormal):""" 登录安全审计 fail_count : 密码错误次数 captcha_ok : 验证码是否正确,True/False account_locked: 账号是否锁定,True/False ip_abnormal : IP是否异常,True/False 返回 result 登录结果:0-允许 1-需二次验证 2-拒绝 3-强制改密 """result=0# 判定D1:错误次数大于等于3 或 账号已锁定iffail_count>=3oraccount_locked:result=2# 判定D2:验证码错误 且 IP异常if(notcaptcha_ok)andip_abnormal:result=1# 判定D3:嵌套判定,外层IP异常,内层错误次数>10ifip_abnormal:iffail_count>10:result=3returnresult请完成以下问题:
- 列出该程序所有独立条件和完整执行路径;
- 分别设计满足判定覆盖、条件覆盖的测试用例;
- 设计满足路径覆盖的全部测试用例,并说明路径覆盖的优缺点。
5.2 标准答案与详细解析
问题1:独立条件 + 完整执行路径
(1)独立条件(共6个)
| 编号 | 条件 | 所在判定 |
|---|---|---|
| C1 | fail_count >= 3 | D1 |
| C2 | account_locked == True | D1 |
| C3 | captcha_ok == False | D2 |
| C4 | ip_abnormal == True | D2 |
| C5 | ip_abnormal == True | D3外层 |
| C6 | fail_count > 10 | D3内层 |
坑点1:C4和C5表达式相同,但属于不同判定中的独立条件,条件覆盖中分别计数。
(2)完整执行路径(共5条)
| 路径 | D1 | D2 | D3外层 | D3内层 | 最终result |
|---|---|---|---|---|---|
| P1 | 假 | 假 | 假 | — | 0 |
| P2 | 真 | 假 | 假 | — | 2 |
| P3 | 假 | 真 | 真 | 假 | 1 |
| P4 | 假 | 假 | 真 | 假 | 0 |
| P5 | 假 | 假 | 真 | 真 | 3 |
坑点2:D2真要求
ip_abnormal=True,D3外层也要求ip_abnormal=True。因此"D2真 + D3外层假"不可达,原路径表中不存在"D2真、D3外层假"的路径。
问题2:判定覆盖、条件覆盖测试用例
(1)判定覆盖
| 用例 | fail_count | captcha_ok | account_locked | ip_abnormal | 覆盖分支 |
|---|---|---|---|---|---|
| 1 | 0 | True | False | False | F1、F2、F3 |
| 2 | 5 | True | True | False | T1、F2、F3 |
| 3 | 0 | False | False | True | F1、T2、T3、F4 |
| 4 | 0 | True | False | True | F1、F2、T3、T4 |
覆盖验证:T1✓ F1✓ T2✓ F2✓ T3✓ F3✓ T4✓ F4✓
(2)条件覆盖
| 用例 | fail_count | captcha_ok | account_locked | ip_abnormal | C1 | C2 | C3 | C4 | C5 | C6 |
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 0 | True | False | False | 假 | 假 | 假 | 假 | 假 | — |
| 2 | 5 | True | False | False | 真 | 假 | 假 | 假 | 假 | — |
| 3 | 0 | False | True | True | 假 | 真 | 真 | 真 | 真 | 假 |
| 4 | 15 | True | False | True | 真 | 假 | 假 | 真 | 真 | 真 |
覆盖验证:C1真假✓ C2真假✓ C3真假✓ C4真假✓ C5真假✓ C6真假✓
问题3:路径覆盖用例 + 优缺点
(1)路径覆盖完整用例
| 用例ID | fail_count | captcha_ok | account_locked | ip_abnormal | 对应路径 | 输出result |
|---|---|---|---|---|---|---|
| 1 | 0 | True | False | False | P1 | 0 |
| 2 | 5 | True | False | False | P2 | 2 |
| 3 | 0 | False | False | True | P3 | 1 |
| 4 | 0 | True | False | True | P4 | 0 |
| 5 | 15 | True | False | True | P5 | 3 |
路径验证:
- P1:D1假、D2假、D3外层假 → result=0 ✓
- P2:D1真、D2假、D3外层假 → result=2 ✓
- P3:D1假、D2真、D3外层真、内层假 → result=1 ✓
- P4:D1假、D2假、D3外层真、内层假 → result=0 ✓
- P5:D1假、D2假、D3外层真、内层真 → result=3 ✓
(2)路径覆盖优缺点
优点
- 白盒测试最高级覆盖标准,100%覆盖所有执行路径
- 可精准发现代码逻辑遗漏、分支失效、路径死区
- 测试覆盖率最高,完整性最强
缺点
- 复杂程序路径数指数级暴涨,用例数量极大
- 测试成本高、效率低,不适合大型项目全量使用
- 仅覆盖代码逻辑,无法检测需求缺失
六、覆盖方法应试速记(冲刺必看)
6.1 高频考点清单
- 强度排序(选择题必考)
- 路径数计算:嵌套判定需逐层分析,外层为假时内层不可达
- 路径可达性:条件间存在约束时,部分路径不可达
- 用例设计:给定代码,写出满足XX覆盖的用例
- 方法辨析:条件覆盖 vs 判定覆盖 vs 判定-条件覆盖
6.2 路径数计算公式
- 顺序结构:路径数 = 1
- if-else:路径数 = 2
- 嵌套if:外层为假时内层不可达
- 循环:路径数 = 循环次数 + 1
- 存在条件约束:需做可达性分析,剔除不可达路径
6.3 答题模板
判定覆盖:判定X有真/假两个分支,分别设计用例:输入__覆盖真分支,输入__覆盖假分支。
条件覆盖:条件C1需取真/假,C2需取真/假……设计用例使每个条件真假至少一次。
路径覆盖:路径1:条件__ → 执行__ → 输出__;路径2:……(需先做可达性分析)
七、博客总结
- 白盒测试核心是基于代码结构的逻辑覆盖测试,六大方法逐级提升覆盖强度;
- 实战中优先使用判定覆盖+条件组合覆盖,平衡测试成本和缺陷覆盖率;
- 高频考点聚焦:覆盖强度排序、路径拆解、用例设计、各方法优缺点辨析;
- 进阶提醒:真实代码中存在条件约束,路径可达性分析是路径覆盖的关键难点;
- 白盒测试是单元测试的核心,是测试工程师底层必备的逻辑测试能力。