等价类划分法(上):有效等价类与无效等价类
很多测试新手拿到一个输入框,第一反应就是「把所有可能的数字都试一遍」。嗯,这种思路我年轻时也干过 —— 结果一个简单的电话号码字段测了三天,还没测完。后来带我的老测试丢过来一句话:「你这不是测试,是穷举。等价类划分搞懂了再说话。」
好,今天咱就把这块硬骨头啃下来。先看一张整体结构图,帮你建立全局印象。
什么是等价类划分?
说白了就是「分门别类」。你把所有可能的输入数据归到几个组里,每组里面的数据对程序来说行为是一样的。我只要从每个组里随便挑一个值测一下,就能代表整个组。
举个例子,一个输入框要求「年龄:1-120之间的整数」。那 -1、0、1、60、120、121、'abc' 这些值该怎么处理?通过等价类划分,我们把它抽象成几个小组:
- 有效等价类:1~120 之间的整数(一个组)
- 无效等价类:小于1的整数、大于120的整数、非整数(小数、字母、特殊字符、空值等)—— 这些都是不同的组
你看,本来要测成千上万个数,现在只需要测几个代表值就够了。效率直接起飞。
有效等价类
有效等价类就是「程序应该正常处理的输入」。说白了,就是符合需求规则的那些数据。
比如一个密码字段,规则是「6-12位字母数字组合」。那有效等价类就是长度为6-12、且只包含字母和数字的字符串。在这个范围内,不管你输入 'abc123' 还是 'xYz890AbC',程序的行为预期是一样的 —— 都通过。
所以有效等价类 一般只有一个(除非规则内部还有多个分支)。
无效等价类
无效等价类则是「程序不应该正常处理的数据」。它们触发的应该是错误提示、拒绝或异常处理。
你想想看,用户可不会乖乖按你的规则来。他们可能会输入负数、超大数字、空字符串、字母、特殊符号、甚至 SQL 注入语句。每一个违规的方向,都应该是一个独立的无效等价类。
为什么无效等价类比有效等价类多? 因为规则只有一条「正确的路」,但偏离的方式有无数种。每一个偏离方式都是一个新的等价类。
| 输入条件 | 有效等价类 | 无效等价类 |
|---|---|---|
| 年龄(1-120整数) | 1~120的整数 | 小于1的整数、大于120的整数、小数、字母、特殊字符、空值 |
| 手机号(11位数字,以1开头) | 11位数字,且以1开头 | 少于11位、多于11位、不以1开头、含字母、空值 |
| 密码(6-12位字母数字) | 6-12位字母数字组合 | 少于6位、多于12位、含特殊字符、纯数字、纯字母、空值 |
划分等价类的通用步骤
好,理论讲完了,咱们来点实在的。我一般按这四步走:
- 识别输入条件 —— 每个输入框、下拉列表、选择框都是独立的输入条件。
- 划分有效等价类 —— 只要规则没拆分,通常就是1个。
- 划分无效等价类 —— 逐条违反规则的方向,每个方向都是1个类。
- 为每个等价类选一个代表值 —— 保证代表值严格属于该类,且不与其他类别重合。
来看一个完整的代码级例子。假如你测的是一个登录界面的「用户名」输入框,需求是「4-20个字符,只能包含字母、数字、下划线」。
// 伪代码:测试用例设计(基于等价类划分)
// 有效等价类:长度4-20,只含字母/数字/下划线
// 代表值: "User_123" (长度8,合规)
// 无效等价类1:长度小于4
// 代表值: "ab" (长度2)
// 预期结果:提示"用户名至少4个字符"
// 无效等价类2:长度大于20
// 代表值: "abcdefghijklmnopqrstuvwxyz12345" (长度30)
// 预期结果:提示"用户名不超过20个字符"
// 无效等价类3:包含非法字符(如空格、@、#等)
// 代表值: "user name"
// 预期结果:提示"只能包含字母、数字、下划线"
// 无效等价类4:空值
// 代表值: ""
// 预期结果:提示"用户名不能为空"
你肯定注意到了,上面我写了4个无效等价类。如果需求里还有「大小写不敏感」的规则,那有效等价类可能还要拆成大写组合、小写组合。看,实际工作中等价类的数量没有定数,取决于规则细节。
常见误区
聊几个我踩过的坑,希望你别再掉进去。
- 把有效等价类当成唯一测试目标 —— 只测正确的数据,忽略无效类。结果上线第一天用户乱输一个字母,系统直接崩溃。
- 无效等价类合并过度 —— 上面说过了,「小于最小值」和「大于最大值」不是同一个错误逻辑,必须分开。
- 代表值选得太激进 —— 比如有效类的代表值选了个边界值(比如1或120),边界测试和等价类测试混在一起,导致边界出问题时分不清是等价类覆盖不全还是边界本身的问题。建议:等价类代表值取中间值,边界值单独测。
有效等价类与无效等价类的对比总结
| 维度 | 有效等价类 | 无效等价类 |
|---|---|---|
| 定义 | 符合规则、程序应正常处理的输入 | 违反规则、程序应拒绝或异常处理的输入 |
| 数量 | 通常1个(规则无分支时) | 多个(取决于规则违反的方向数) |
| 代表值选取 | 选典型中间值,避免边界 | 每类选一个典型的违规值 |
| 测试目标 | 验证核心功能正确可用 | 验证容错和异常处理能力 |
| 常见遗漏 | 较少(因为好理解) | 极其容易遗漏(尤其是空值、超长、特殊符号等) |
最后说一句,等价类划分法是测试设计的基础,也是性价比最高的方法之一。你别觉得简单就轻视它 —— 我见过很多五年经验的测试,还在因为等价类划分不清导致漏测。把有效类和无效类的逻辑想透了,你的测试覆盖率至少翻一倍。