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 实战步骤

我一般这么用因果图:

  1. 列出所有原因(输入条件)和结果(输出或动作)。
  2. 画出因果图,用逻辑符号连接原因和结果。
  3. 转换成判定表,列出所有可能的条件组合。
  4. 简化判定表,去掉冗余组合。
  5. 生成测试用例,每个组合对应一个用例。

举个例子,一个台架测试的「过温保护」功能:

  • 原因:温度 > 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
避坑指南:我曾经在一个项目里,因果图画了 20 多个原因,结果判定表有 2^20 行——根本测不完。后来发现很多原因其实是互斥的,简化后只剩 12 个组合。所以,画因果图之前,先看看能不能合并原因。

4.4 正交实验法:用最少用例覆盖最多组合

正交实验法解决的是组合爆炸的问题。当你有多个因素、每个因素有多个水平时,全组合测试的用例数会指数级增长。正交实验法能帮你用最少的用例,覆盖最广的组合。

4.4.1 基本概念

  • 因素:影响结果的变量,比如温度、湿度、电压。
  • 水平:每个因素的可能取值,比如温度有 25°C、50°C、75°C 三个水平。
  • 正交表:一种特殊的表格,任意两列中,所有可能的水平组合出现次数相同。

4.4.2 实战步骤

我一般这么用正交实验法:

  1. 确定因素和水平:列出所有影响测试结果的因素,以及每个因素的水平。
  2. 选择正交表:根据因素数和水平数,选择合适的正交表。
  3. 映射到正交表:把因素和水平填入正交表。
  4. 生成测试用例:正交表的每一行就是一个测试用例。

举个例子,一个台架测试有 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 本章知识结构图

下面这张图展示了五种方法的关系和适用场景:

测试用例设计方法知识结构图 测试用例设计方法 等价类划分 边界值分析 因果图法 正交实验法 场景法 组合使用建议 等价类 + 边界值:打底 因果图 + 正交:降维 场景法:串流程 输入范围明确 边界 bug 高发 条件组合逻辑 多因素降维 用户操作流程

4.8 实战建议

最后,分享几个我在项目中积累的经验:

  • 先粗后细:先用场景法画出主流程,再用等价类划分和边界值分析细化每个步骤的输入。
  • 组合使用:因果图法和正交实验法搭配使用效果最好——因果图理逻辑,正交表降维。
  • 不要贪多:一个功能点,等价类划分 + 边界值分析基本能覆盖 90% 的 bug。剩下的 10%,用因果图法和场景法补上。
  • 记录遗漏:每次线上故障,都回头看看是哪种方法没覆盖到。久而久之,你的用例设计能力会越来越强。
我的习惯:我每做完一个项目的测试用例设计,都会花半小时复盘——哪些 bug 是等价类划分漏的?哪些是边界值分析漏的?然后更新我的用例设计模板。这样,下一个项目就能少踩坑。