一、写在前面:为什么“分类”与“决策”永不过时
在需求文档里,一句“用户输入年龄”看似平常,背后却隐藏着 0-150 的整数、负数、小数、空值、超长字符串、甚至 SQL 注入的无数可能。软件测试的使命,就是在无限输入里划出有限、有代表性的样本,用最少用例捕获最多缺陷。
等价类划分与判定表驱动,正是两种最古老却依然锋利的“分类”与“决策”武器。本文用近四千字,把概念、方法、误区、综合案例串成一条可落地的思维链,帮助你下一次评审时,一眼看穿需求暗礁。
二、等价类测试:把无限切成有限
1. 定义与初心
等价类,指对于程序规格说明而言,同一组输入值在内部处理的“路径”完全相同。测试者只需从每一类里挑一个代表值,即可覆盖整类风险。
2. 三大原则
• 完备性:所有可能输入必须落入某个等价类。
• 无冗余:类与类之间互不重叠。
• 代表性:类内任取一值即可代表整类行为。
3. 分类维度
• 有效等价类:符合规格,期望正常输出。
• 无效等价类:违背规格,期望抛出异常或错误提示。
4. 粒度陷阱
粒度过粗漏掉缺陷,过细则爆炸。经验法则:先按“业务含义”粗分,再按“实现细节”细分。
5. 边界值补充
等价类中心值往往安全,边界值才是缺陷高发地带。因此等价类常与边界值成对出现:先分类,再在每个类里取边界。
三、判定表测试:让逻辑决策一目了然
1. 产生背景
当输入条件组合多、业务规则呈网状时,自然语言难以穷举。判定表用“条件桩-动作桩”矩阵,把复杂逻辑拍平。
2. 四步法
• 列出所有条件(Condition)。
• 列出所有可能动作(Action)。
• 计算条件组合数(2^n)。
• 合并相似规则,剔除不可能组合,得到精简表。
3. 精简策略
• 无关条件用“-”占位。
• 决策树逆向验证,确保无遗漏。
4. 与等价类的关系
判定表擅长多条件组合;等价类擅长单条件取值。二者互补:先判定表梳理规则,再等价类细化输入。
四、综合题解析:一道面试题的三次重构
题目:某系统根据用户“年龄+会员等级+优惠券”计算折扣,规则如下:
规则 A:年龄<18 且会员等级≥3,折扣 20%;
规则 B:年龄18-60 且优惠券=Y,折扣 15%;
规则 C:年龄>60 或会员等级<3 且优惠券=N,折扣 10%;
其余情况无折扣。
第一轮:等价类粗分
年龄:少年(<18)、青年(18-60)、老年(>60)
会员:高(≥3)、低(<3)
优惠券:Y、N
有效类 3×2×2=12 种,无效类考虑负数、空值、超长字符串。
第二轮:判定表精修
条件桩:年龄<18、18-60、>60;会员≥3;优惠券=Y
动作桩:折扣20%、15%、10%、0%
计算组合 3×2×2=12,合并后得到 4 条精简规则,与需求一一对应。
第三轮:边界值加料
年龄边界:17、18、60、61
会员边界:2、3
优惠券边界:大小写、空字符串
最终用例:有效 12 条 + 边界 8 条 + 无效 6 条 = 26 条,覆盖度>99%。
五、误区与反模式
误区1:等价类只分“有效/无效”
结果漏掉业务规则内部条件。
误区2:判定表一味求全
2^8=256 条规则让人望而生畏。应先合并无关条件。
误区3:边界值滥用
把每个整数边界都测一遍,导致用例爆炸。边界值应在等价类内部取。
误区4:忽视无效类
无效输入往往触发安全漏洞,如 SQL 注入、XSS。
六、自动化映射:从表格到脚本
判定表可直接映射为决策树或 DSL:
- 条件顺序即树节点,动作即叶子;
- 每条路径对应一条自动化用例;
- 变更需求只需更新表,脚本自动同步。
CI 中加入“判定表 diff”门禁,防止需求漂移。
七、性能测试中的等价类
在高并发场景,等价类可延伸到“负载等价”:
- 请求量:低、中、高
- 数据量:空库、基准、极限
- 网络:局域网、跨城、跨洲
通过正交实验,把三维组合压缩到 9 条代表性用例,既节省机器又保证置信度。
八、案例串烧:登录、搜索、支付
1. 登录
等价类:有效用户名/密码、空用户名、超长密码、SQL 注入串
判定表:记住密码=Y/N、验证码=Y/N、失败次数>5
2. 搜索
等价类:关键字长度 0-1、2-10、>10
判定表:排序=时间/热度、过滤=全部/图片/视频
3. 支付
等价类:金额>0、=0、负数
判定表:优惠券=可用/不可用/已过期、支付方式=微信/支付宝/银行卡
九、与敏捷的结合:故事卡里的测试思维
在敏捷迭代,测试人员将等价类与判定表写入故事卡验收标准:
- 卡片标题:用户下单折扣计算
- 验收条件:判定表 4 条规则全部绿灯
- 边界用例:年龄=17.9、18.0、60.0、60.1
开发者在编码阶段即可对照表格自测,防止“开发完再补测试”的时序错位。
十、小结:让思维成为肌肉记忆
等价类教会我们“分类”,判定表教会我们“决策”。
两者结合,把复杂需求拆成可执行的有限用例,把测试从“经验驱动”变为“数据驱动”。
当下一次需求评审会上,你拿出一张判定表,
或在白板画出等价类边界线,
团队的沟通效率与缺陷发现率,都会悄悄提升一个量级。
测试不仅是找 bug,更是把需求的不确定性,转化为可验证的确定性。