等价类划分法:从原理到实战
等价类划分,说白了就是「把无穷的输入,分成有限的几类」。
我刚开始做测试那会儿,总觉得要测遍所有输入才放心。后来一个登录框就让我测了三天——用户名、密码、验证码,各种组合,测到吐。直到老前辈甩给我一句话:「你不需要测所有,你只需要测每一类。」
嗯,这就是等价类划分的核心思想。
原理与定义
等价类划分法的理论基础很简单:如果某个输入条件能代表一类输入,那么这一类里的任何一个值,测出来的结果应该是一样的。
举个例子。一个输入框要求输入 1-100 的整数。你测了 50,那 51、52、53 还有必要测吗?没必要。因为它们属于同一个等价类——有效范围内的整数。
核心定义:等价类是指输入域中具有相同行为的一组数据。从其中一个数据能发现的问题,从同类其他数据中也能发现。
这里有两个关键概念:
- 有效等价类:符合需求、程序应该正常处理的输入
- 无效等价类:不符合需求、程序应该拒绝或报错的输入
我个人的习惯是:先画有效等价类,再画无效等价类。为什么?因为有效等价类决定了「功能能不能跑通」,无效等价类决定了「程序扛不扛揍」。两者缺一不可。
有效等价类与无效等价类
咱们用一个实际例子来拆解。假设有个年龄输入框,需求写的是「18-60 岁的整数」。
| 类别 | 等价类 | 示例值 | 预期结果 |
|---|---|---|---|
| 有效 | 18-60 之间的整数 | 25、30、45 | 通过 |
| 无效 | 小于 18 的整数 | 10、17 | 提示「年龄不合法」 |
| 无效 | 大于 60 的整数 | 61、80 | 提示「年龄不合法」 |
| 无效 | 非整数 | 25.5、abc | 提示「请输入整数」 |
| 无效 | 空值 | (不输入) | 提示「年龄不能为空」 |
你看,5 个等价类,5 条用例,就把整个输入域覆盖了。如果不用等价类,光整数就有 43 种可能,再加上小数、字符、空值……测到猴年马月。
我的经验:无效等价类往往比有效等价类更容易发现 Bug。我在项目中遇到过好几次,开发只处理了「有效输入」,对「无效输入」直接抛异常或者白屏。所以,无效等价类一定要写全。
实战案例:登录模块测试
登录模块,每个测试人员都测过。但你真的测全了吗?
咱们拿一个典型的登录需求来分析:
- 用户名:6-20 位字母或数字
- 密码:8-16 位,必须包含字母和数字
- 验证码:4 位数字
先画等价类。我习惯用表格来梳理:
| 输入项 | 有效等价类 | 无效等价类 |
|---|---|---|
| 用户名 | 6-20 位字母数字组合 | 小于 6 位、大于 20 位、含特殊字符、空值 |
| 密码 | 8-16 位含字母和数字 | 小于 8 位、大于 16 位、纯字母、纯数字、空值 |
| 验证码 | 4 位数字 | 少于 4 位、多于 4 位、含字母、空值 |
有了这个表,用例就很好写了。每个有效等价类取一个值,每个无效等价类取一个值,组合起来就是一套完整的测试用例。
举个例子,针对用户名的无效等价类:
用例 1:用户名 5 位(小于 6 位)→ 预期:提示「用户名长度不合法」
用例 2:用户名 21 位(大于 20 位)→ 预期:提示「用户名长度不合法」
用例 3:用户名含 @ 符号 → 预期:提示「用户名只能包含字母和数字」
用例 4:用户名为空 → 预期:提示「用户名不能为空」
你想想看,如果不做等价类划分,你可能只会测「正确的用户名+正确的密码+正确的验证码」,然后觉得登录功能没问题。但上线后用户输入了一个特殊字符,程序直接崩了——这种事故我见过不止一次。
避坑指南:我曾经在一个项目中,只测了有效等价类,忽略了「密码纯数字」这个无效等价类。结果上线后,用户设置了一个纯数字密码,系统竟然通过了——因为开发只校验了长度,没校验字符类型。从那以后,我每次都会问自己:「无效等价类,我写全了吗?」
等价类划分的核心流程
我总结了一个四步法,你直接拿去用:
- 识别输入条件:每个输入框、每个参数、每个选项,都是潜在的等价类来源
- 划分等价类:先有效、再无效,每个条件至少一个有效类、若干个无效类
- 编号管理:给每个等价类一个唯一编号,方便后续用例追溯
- 生成用例:每个等价类至少覆盖一次,无效等价类单独成用例
下面这张图,把整个流程串起来了:
常见误区
等价类划分看着简单,但实际用起来容易踩坑。我列几个常见的:
- 只划分不编号:用例多了之后,根本不知道哪个等价类覆盖了没有。编号是管理的基础。
- 忽略组合场景:等价类划分解决的是「单个输入」的问题,多个输入之间的组合,需要用正交法或判定表。别混为一谈。
- 无效等价类写太少:我见过有人只写一个「不符合要求」的无效类,把所有非法输入都塞进去。这样不行,不同类型的无效输入要分开。
- 等价类划分过细:比如 1-100 的整数,你分成 1-10、11-20、21-30……这就过度设计了。等价类的粒度,以「行为是否一致」为准。
一个小技巧:如果你不确定某个等价类该不该单独划分,就问自己一个问题:「这个值和另一个值,程序的处理逻辑会不一样吗?」如果会,就分开;如果不会,就合并。
等价类划分法,是测试用例设计的基石。它不复杂,但需要刻意练习。我建议你从手边的项目开始,随便找一个输入框,试着画一画等价类。画完之后,再对照实际测试结果,看看有没有遗漏。慢慢地,你就会形成一种「等价类思维」——看到任何输入,脑子里自动就开始分类了。