等价类划分法:从原理到实战
等价类划分,说白了就是「把输入数据分堆儿」。
你想想看,测试不可能把所有输入都试一遍。一个年龄输入框,从0到200,难道每个数字都测?那项目得测到猴年马月去。等价类的核心思想就是:挑一个代表,测一堆数据。
原理:为什么能「以一代全」?
我刚开始做测试时也不理解——凭什么选一个就能代表全部?后来踩了坑才明白:程序对同一类数据的处理逻辑是一样的。
比如年龄输入框,程序判断逻辑通常是:
- 如果年龄在18-60之间,走「成年人」分支
- 如果小于18,走「未成年人」分支
- 如果大于60,走「老年人」分支
你看,18、25、40、55,这四个数在程序眼里其实是一回事——都落在18-60这个区间里。所以只要测一个25,就能代表整个区间。
核心原则:等价类划分的前提是「程序对同类数据的处理路径相同」。如果处理逻辑不同,那就得拆成不同的等价类。
有效等价类 vs 无效等价类
这是新手最容易搞混的地方。我简单说:
- 有效等价类:符合需求、程序能正常处理的数据
- 无效等价类:不符合需求、程序应该拒绝或报错的数据
举个例子,一个手机号验证功能,需求写的是「11位数字,以1开头」:
| 类型 | 等价类 | 示例 |
|---|---|---|
| 有效 | 11位数字,以1开头 | 13800138000 |
| 无效 | 少于11位 | 1380013800 |
| 无效 | 多于11位 | 138001380000 |
| 无效 | 不以1开头 | 23800138000 |
| 无效 | 包含非数字字符 | 13800abc000 |
| 无效 | 为空 | (空字符串) |
我曾经踩过的坑:只测了有效等价类,觉得功能没问题就提交了。结果上线后用户输入了「13800 138000」(中间有空格),程序直接崩了。从那以后,我每次都会把无效等价类列得比有效还多。
实战案例:年龄输入框
假设需求是「年龄输入框,只接受18-60岁的整数」:
// 等价类划分结果
有效等价类:
- 18 ≤ 年龄 ≤ 60 的整数 → 选 25
无效等价类:
- 年龄 < 18 的整数 → 选 15
- 年龄 > 60 的整数 → 选 65
- 小数 → 选 25.5
- 非数字字符 → 选 "abc"
- 负数 → 选 -5
- 为空 → 选 ""
我个人习惯是,每个等价类至少选一个代表值。但注意:边界值要单独拿出来测,这个后面会讲。
实战案例:手机号验证
需求:11位数字,以1开头,第二位是3/5/7/8/9。
| 等价类 | 代表值 | 预期结果 |
|---|---|---|
| 有效:11位,1开头,第二位合法 | 13812345678 | 验证通过 |
| 无效:第二位不合法(如2) | 12812345678 | 提示「手机号格式错误」 |
| 无效:10位 | 1381234567 | 提示「手机号长度错误」 |
| 无效:12位 | 138123456789 | 提示「手机号长度错误」 |
| 无效:包含字母 | 138abc56789 | 提示「请输入数字」 |
我的小技巧:写用例时,把「有效等价类」和「无效等价类」分开列。无效的用例要写清楚「预期错误提示」,这样自动化断言时才知道该抓什么。
边界值分析法:等价类的好搭档
等价类划分有个弱点——它不关心边界。而程序出bug,十有八九都在边界上。
比如年龄18-60,等价类只测了25。但18和60这两个边界值呢?还有17、19、59、61呢?
边界值分析法的原则:
- 取边界值本身(上点):18、60
- 取边界值相邻的值(离点):17、19、59、61
- 如果边界是开区间,还要考虑内点
我建议的实践方式是:先用等价类划分确定「测哪些类」,再用边界值分析确定「测哪些具体值」。
// 年龄输入框的完整测试数据
等价类代表值:25(有效类)
边界值:17, 18, 19, 59, 60, 61
无效类代表值:-5, 25.5, "abc", ""
你看,这样组合下来,测试数据既全面又精简。一共才10个值,但覆盖了所有可能出问题的点。
知识体系图
下面这张图总结了等价类划分与边界值分析的关系:
避坑指南
我这些年总结的几个常见坑:
- 别把等价类分得太细:比如年龄18-60,有人非要分成18-30、31-45、46-60三个类。除非程序对这三个区间有不同处理逻辑,否则就是过度设计。
- 无效等价类别漏了「空值」和「特殊字符」:这是最容易被忽略的。我见过一个项目,所有功能都测了,唯独没测输入为空的情况,结果上线第一天就崩了。
- 边界值别忘了「开区间」和「闭区间」:需求写的是「18-60(含)」,那18和60就是有效边界。如果写的是「18-60(不含)」,那19和59才是有效边界。一字之差,测试数据完全不同。
一句话总结:等价类划分让你知道「测哪些类型」,边界值分析让你知道「测哪些具体值」。两者结合,才是完整的测试数据设计方法。