4. 测试用例设计:等价类划分、边界值分析、因果图法、正交实验法、场景法
测试用例设计,说白了就是回答一个问题:测哪些、怎么测、测多少才算够。
我刚入行那会儿,觉得测试就是对着需求一条条点过去。后来被一个线上故障狠狠教育了一回——一个输入框,我测了正常值、最大值、最小值,偏偏漏了空值。结果上线第一天,用户啥都不填直接提交,系统崩了。
从那以后,我老老实实把用例设计方法学了一遍。今天这五种方法,是我在台架测试里用得最多的。咱们一个一个说。
4.1 等价类划分:把无穷变成有限
等价类划分的思路很简单:把输入数据分成若干类,每类里挑一个代表测就行。
为什么?因为同一类里的数据,程序处理逻辑是一样的。你测了 18 岁,就没必要再测 19 岁、20 岁——它们都属于「有效成年人」这个等价类。
4.1.1 有效等价类 vs 无效等价类
我习惯把等价类分成两种:
- 有效等价类:符合需求、程序应该正常处理的输入。
- 无效等价类:不符合需求、程序应该拒绝或报错的输入。
举个例子,一个台架测试的温度输入范围是 0°C ~ 100°C:
| 输入条件 | 有效等价类 | 无效等价类 |
|---|---|---|
| 温度值 | 0 ≤ T ≤ 100 | T < 0, T > 100 |
| 数据类型 | 整数、浮点数 | 字符串、特殊字符、空值 |
| 精度 | 小数点后 1 位 | 小数点后 2 位及以上 |
4.1.2 划分原则
等价类划分不是瞎分的,有几个原则:
- 完备性:所有可能的输入都要被某个等价类覆盖。
- 互斥性:一个输入只能属于一个等价类。
- 代表性:每个等价类里的数据,程序处理逻辑相同。
你想想看,如果两个输入的处理逻辑不同,那它们就不该分在同一个等价类里。比如「0°C」和「0.1°C」,虽然数值接近,但如果程序对整数和浮点数有不同处理,那就得分开。
4.2 边界值分析:bug 最爱藏在边界
经验告诉我,80% 的 bug 都出在边界上。为什么?因为程序员写条件判断时,最容易写错的就是边界——比如把 if (x >= 0) 写成 if (x > 0)。
4.2.1 边界值选取规则
对于区间 [min, max],我一般取这些值:
- 最小值:min
- 略大于最小值:min + 1
- 略小于最小值:min - 1(如果允许)
- 最大值:max
- 略小于最大值:max - 1
- 略大于最大值:max + 1(如果允许)
举个例子,一个台架测试的电压输入范围是 5V ~ 24V:
| 边界类型 | 测试值 | 预期结果 |
|---|---|---|
| 下边界 | 5.0V | 正常 |
| 下边界 + 1 | 5.1V | 正常 |
| 下边界 - 1 | 4.9V | 报错 |
| 上边界 | 24.0V | 正常 |
| 上边界 - 1 | 23.9V | 正常 |
| 上边界 + 1 | 24.1V | 报错 |
4.3 因果图法:理清逻辑关系
因果图法适合处理多个条件组合决定一个结果的场景。比如:
- 如果温度过高 且 持续时间超过 10 秒,则触发报警。
- 如果温度过高 但 持续时间不超过 10 秒,则只记录日志。
这种逻辑关系,用等价类划分和边界值分析很难覆盖全。因果图法就是专门干这个的。
4.3.1 基本符号
因果图里常用的逻辑关系:
- 恒等:原因出现,结果就出现。
- 非:原因不出现,结果才出现。
- 与:多个原因同时出现,结果才出现。
- 或:多个原因中至少一个出现,结果就出现。
4.3.2 实战步骤
我一般这么用因果图:
- 列出所有原因(输入条件)和结果(输出或动作)。
- 画出因果图,用逻辑符号连接原因和结果。
- 转换成判定表,列出所有可能的条件组合。
- 简化判定表,去掉冗余组合。
- 生成测试用例,每个组合对应一个用例。
举个例子,一个台架测试的「过温保护」功能:
- 原因:温度 > 85°C(C1)、持续时间 > 10s(C2)
- 结果:触发报警(E1)、记录日志(E2)
- 逻辑:C1 且 C2 → E1;C1 且 非 C2 → E2
对应的判定表:
| C1(温度 > 85°C) | C2(持续时间 > 10s) | E1(触发报警) | E2(记录日志) |
|---|---|---|---|
| 0 | 0 | 0 | 0 |
| 0 | 1 | 0 | 0 |
| 1 | 0 | 0 | 1 |
| 1 | 1 | 1 | 1 |
4.4 正交实验法:用最少用例覆盖最多组合
正交实验法解决的是组合爆炸的问题。当你有多个因素、每个因素有多个水平时,全组合测试的用例数会指数级增长。正交实验法能帮你用最少的用例,覆盖最广的组合。
4.4.1 基本概念
- 因素:影响结果的变量,比如温度、湿度、电压。
- 水平:每个因素的可能取值,比如温度有 25°C、50°C、75°C 三个水平。
- 正交表:一种特殊的表格,任意两列中,所有可能的水平组合出现次数相同。
4.4.2 实战步骤
我一般这么用正交实验法:
- 确定因素和水平:列出所有影响测试结果的因素,以及每个因素的水平。
- 选择正交表:根据因素数和水平数,选择合适的正交表。
- 映射到正交表:把因素和水平填入正交表。
- 生成测试用例:正交表的每一行就是一个测试用例。
举个例子,一个台架测试有 3 个因素,每个因素 2 个水平:
- 温度:25°C、50°C
- 湿度:30%、60%
- 电压:12V、24V
全组合需要 2^3 = 8 个用例。用正交表 L4(2^3),只需要 4 个用例:
| 用例 | 温度 | 湿度 | 电压 |
|---|---|---|---|
| 1 | 25°C | 30% | 12V |
| 2 | 25°C | 60% | 24V |
| 3 | 50°C | 30% | 24V |
| 4 | 50°C | 60% | 12V |
4.5 场景法:从用户视角出发
场景法,说白了就是模拟用户的操作流程。它不关心单个输入,而是关心一系列操作组合起来的结果。
4.5.1 基本流 vs 备选流
- 基本流:用户最常用的、最顺利的操作路径。
- 备选流:用户可能遇到的异常或分支路径。
举个例子,一个台架测试的「启动测试」功能:
- 基本流:连接设备 → 选择测试项目 → 点击启动 → 测试完成 → 生成报告。
- 备选流 1:连接设备失败 → 提示错误 → 重试连接。
- 备选流 2:测试过程中设备断开 → 暂停测试 → 恢复连接 → 继续测试。
- 备选流 3:测试结果异常 → 标记为失败 → 记录日志 → 继续下一个测试。
4.5.2 场景法 vs 其他方法
场景法和前面几种方法不冲突,反而是互补的:
- 等价类划分、边界值分析、因果图法、正交实验法:关注单个功能点的输入输出。
- 场景法:关注多个功能点的组合流程。
我一般先用例设计方法把单个功能点测透,再用场景法把整个流程串起来。这样既能保证深度,又能保证广度。
4.6 五种方法对比总结
| 方法 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 等价类划分 | 输入数据范围明确 | 简单高效,减少冗余 | 无法覆盖边界和组合 |
| 边界值分析 | 输入有明确边界 | 发现边界 bug 能力强 | 只关注边界,忽略中间值 |
| 因果图法 | 多个条件组合决定结果 | 理清逻辑关系,覆盖全 | 因素多时判定表爆炸 |
| 正交实验法 | 多因素多水平组合 | 用最少用例覆盖最广 | 忽略交互作用 |
| 场景法 | 用户操作流程 | 贴近真实使用 | 容易漏异常场景 |
4.7 本章知识结构图
下面这张图展示了五种方法的关系和适用场景:
4.8 实战建议
最后,分享几个我在项目中积累的经验:
- 先粗后细:先用场景法画出主流程,再用等价类划分和边界值分析细化每个步骤的输入。
- 组合使用:因果图法和正交实验法搭配使用效果最好——因果图理逻辑,正交表降维。
- 不要贪多:一个功能点,等价类划分 + 边界值分析基本能覆盖 90% 的 bug。剩下的 10%,用因果图法和场景法补上。
- 记录遗漏:每次线上故障,都回头看看是哪种方法没覆盖到。久而久之,你的用例设计能力会越来越强。