等价类划分法:原理与概念

等价类划分,说白了就是「把输入数据分堆」。

我刚开始做测试那会儿,总觉得要测遍所有输入才放心。后来发现,这根本不现实。你想想看,一个登录框,光用户名就能输入几十亿种组合,全测完?项目早黄了。

等价类划分的核心思想很简单:把无穷的输入,变成有限的几类。同一类里的数据,程序处理方式是一样的。测一个,就等于测了一堆。

有效等价类 vs 无效等价类

这里有个关键点,我当年踩过坑——有效等价类和无效等价类,必须分开考虑

  • 有效等价类:符合需求、程序能正常处理的输入。比如登录时,正确的用户名+正确的密码。
  • 无效等价类:不符合需求、程序应该拒绝的输入。比如用户名太短、密码错误、包含特殊字符等。

重要原则:有效等价类只测一个值,无效等价类每个都要单独测。

为什么?因为多个无效输入同时出现时,你根本不知道是哪个触发了错误。我曾经在项目中吃过这个亏,测了半天发现是多个bug叠加了,排查起来特别痛苦。

实战案例:登录模块

拿登录模块来说,需求是这样的:

  • 用户名:6-18位字母或数字
  • 密码:8-20位,必须包含字母和数字
  • 验证码:4位数字

嗯,这里要注意,需求里没说的边界情况,恰恰是bug的高发区。

第一步:划分等价类

输入项有效等价类无效等价类
用户名6-18位字母/数字小于6位、大于18位、含特殊字符、为空
密码8-20位含字母+数字小于8位、大于20位、纯字母、纯数字、为空
验证码4位数字非4位、含字母、为空

我的习惯:画等价类表时,我会在边上标注「边界值」。比如用户名6-18位,那5、6、7、17、18、19这些值,我后面做边界值分析时会重点测。等价类和边界值,从来都是搭档。

第二步:设计测试用例

有效等价类,我一般只设计一条用例:

用例1:用户名"testuser123"(10位字母数字),密码"Pass1234"(8位含字母数字),验证码"1234"
预期结果:登录成功

无效等价类,每个都要单独测:

用例2:用户名"abc"(小于6位),密码"Pass1234",验证码"1234"
预期结果:提示「用户名长度需6-18位」

用例3:用户名"testuser123456789"(大于18位),密码"Pass1234",验证码"1234"
预期结果:提示「用户名长度需6-18位」

用例4:用户名"test@user"(含特殊字符),密码"Pass1234",验证码"1234"
预期结果:提示「用户名只能包含字母或数字」

用例5:用户名""(为空),密码"Pass1234",验证码"1234"
预期结果:提示「请输入用户名」

我曾经踩过的坑:有一次测登录,我同时用了错误用户名+错误密码+错误验证码。结果系统只报了「验证码错误」,修复验证码后,又报「密码错误」……来回折腾了好几轮。后来我才意识到,无效等价类必须单独测,否则你根本不知道哪个输入才是真正的罪魁祸首。

第三步:补充边界值

等价类划分搞定后,我会顺手把边界值也加上。这两个方法从来都是搭配使用的:

用例6:用户名"abcde"(5位,边界下),密码"Pass1234",验证码"1234"
预期结果:提示「用户名长度需6-18位」

用例7:用户名"abcdef"(6位,边界上),密码"Pass1234",验证码"1234"
预期结果:登录成功

用例8:用户名"abcdefghijklmnopqr"(18位,边界上),密码"Pass1234",验证码"1234"
预期结果:登录成功

用例9:用户名"abcdefghijklmnopqrs"(19位,边界上),密码"Pass1234",验证码"1234"
预期结果:提示「用户名长度需6-18位」

等价类划分的常见误区

我见过不少测试新人,包括当年的我自己,容易犯这几个错:

  1. 只关注有效等价类——无效等价类才是bug的重灾区。我统计过,项目中70%以上的bug都是在无效输入时触发的。
  2. 无效等价类合并测试——前面说过了,千万别合并。每个无效等价类单独一条用例。
  3. 忽略隐含等价类——比如登录模块的「记住密码」功能,虽然需求里没提,但「勾选」和「不勾选」就是两个等价类。我建议你多想想「用户还可能怎么操作」。

一个小技巧:画等价类时,试着从「用户视角」和「开发者视角」各看一遍。用户视角关注输入是否合理,开发者视角关注代码里有没有特殊处理。两个视角一交叉,漏掉的等价类就出来了。

总结

等价类划分,说白了就是「用最少的用例,覆盖最多的场景」。它不复杂,但需要你多想一步——哪些输入是程序能处理的,哪些是它应该拒绝的。

我个人习惯,拿到需求后先画等价类表,再补充边界值,最后才动手写用例。顺序对了,效率自然就上来了。

下一章,我会讲边界值分析法。这两个方法,你想想看,是不是天生一对?