3、穷举测试方法:全组合测试策略归纳总结
说到穷举测试,很多人第一反应就是“不可能”。确实,项目里参数一多,组合数就炸了。我记得刚带团队做嵌入式协议栈测试时,一个配置接口有 6 个参数,每个参数 3~5 个取值,全组合大概 4k 多条用例。团队硬跑了一遍,花了整整两周。后来发现,真正能找到问题的组合其实就那么几十个。
所以全组合测试策略,并不是让你真把全部组合都跑一遍,而是用一套方法找出“最能揭露缺陷的那批组合”。说白了,就是一种有优先级、有取舍的穷举。下面我把这些年积累的几种典型策略梳理一下。
什么是全组合测试策略
全组合策略的核心思想是:“覆盖所有可能影响行为的参数取值组合,但只覆盖你选定范围内的”。它通常包含两个步骤:
- 参数筛选 – 从所有输入参数里选出真正重要的,忽略不会引起行为变化的。
- 覆盖模型选择 – 决定是两两覆盖(Pairwise),还是三三覆盖(3-wise),还是全部覆盖(全因子)。
我个人的习惯是:先做等价类划分和边界值分析,把每个参数的取值压到一个很小的集合(通常 2~4 个)。然后再用 Pairwise 工具生成测试用例。98% 的项目这样做就够了。剩下的 2% ——比如航空、医疗、汽车领域——我才会上 3-wise 甚至 4-wise。
| 策略名称 | 覆盖力度 | 用例数量(6参×4值) | 常用场景 |
|---|---|---|---|
| 全因子 (Full Factorial) | 100% 所有组合 | 4⁶ = 4096 | 安全性关键系统、少量参数 |
| 两两组合 (Pairwise) | 所有参数对至少出现一次 | ~40~60(工具生成) | 通用软件、Web、API 测试 |
| 三三组合 (3-wise) | 所有三元组至少出现一次 | ~200~400 | 金融、通信协议 |
| 正交表 (Orthogonal Array) | 均衡配对,部分交互覆盖 | ~16~64 | 硬件工装、实验设计 |
参数筛选:把 100 个变成 4 个
全组合策略的第一步,往往不是选覆盖模型,而是“砍参数”。我见过太多测试计划把日志级别、缓存开关这种无关参数也放进来,结果组合爆炸。
等价类划分:把每个参数的无穷取值缩成有限等价类。比如“连接超时”参数,只需要测 0(立即超时)、1~5000(正常范围)、5001~65535(边界)三个等价类。
边界值分析:对每个等价类的边界取 min-1, min, min+1, max-1, max, max+1。这六个值经常能暴露越界问题。我曾经在一次协议栈压测中,就是因为漏测了 max+1 这个边界,导致线上数据包被截断。
剔除互斥参数:两个参数如果永远不同时生效(比如“加密方式:AES/无”和“加密密钥”),那就直接组合忽略,PICT 工具可以用约束来处理。
Pairwise:两两覆盖就够了
Pairwise 的原理很简单:绝大多数 bug 都是由两个参数共同作用触发的,三个以上参数同时异常的概率极低。所以只要我们确保每对参数值的组合都至少被一条用例覆盖,就能用很少的用例发现 90% 以上的组合性缺陷。
拿一个实际例子来说。假设有三个参数:
- 浏览器:Chrome, Firefox, Edge
- 操作系统:Win10, macOS, Linux
- 网络:WiFi, 4G, 以太网
全组合是 27 条。而 Pairwise 只需要 9 条即可覆盖所有“浏览器×操作系统”、“浏览器×网络”、“操作系统×网络”的配对。怎么做到的?工具会智能地复用已覆盖的对,并尽量压缩用例数量。
生成 Pairwise 用例最常用的开源工具是 PICT(来自微软)。用法就一行:
pict model.txt > testcases.csv
模型文件 model.txt 的写法也很简单:
Browser: Chrome, Firefox, Edge
OS: Win10, macOS, Linux
Network: WiFi, 4G, Ethernet
# 约束:Chrome 不支持 Linux(示例)
IF [Browser] = "Chrome" THEN [OS] <> "Linux";
输出是一个 CSV,每一行就是一条测试用例。你只需要把另外的测试数据准备逻辑封装好,直接喂给自动化框架就行。
知识体系:从穷举到Pairwise的决策路径
下面这张图帮你把整个选择过程梳理清楚。核心就是三个分支:参数个数、每个参数的值数量、以及你对缺陷风险的容忍度。
工具与自动化集成
除了 PICT,还有几个常用工具:
- AllPairs(Python) – 轻量级,适合小规模组合
- ACTS(美国国家标准与技术研究院) – 支持 t-way 组合,学术背景强
- CIT Hub(开源 Java) – 交互式设计,有 GUI
我个人最常用 PICT,因为它约束表达能力强,而且输出可以直接被 CI 脚本解析。下面是把它集成进 GitLab CI 的一个小片段:
test-pairwise:
stage: test
script:
- pict model.txt > cases.csv
- python -m pytest --csv=cases.csv tests/
IF [OS] = "Windows" THEN [Browser] = "Edge" 这样的约束,把不合理的组合直接剪掉。这样生成的用例更贴近真实使用场景,避免了“Linux 上跑 Safari”这种无用用例。
稀释与扩展:从 Pairwise 到 N-wise
当你发现 Pairwise 还有些 bug 抓不到时,不要急着下结论。先检查是不是参数筛选漏了重要值,还是真的需要更高阶组合。我做过一次统计:在同一个项目里,Pairwise 能找到 92% 的缺陷,3-wise 能到 98%,4-wise 也就 99.2%。多出来的那 1% 成本翻了好多倍,值不值?
所以除非你的测试对象是生命攸关的系统,否则 Pairwise + 边界值分析 + 随机烟雾测试 就足够覆盖绝大多数场景了。如果确实需要 N-wise,PICT 可以直接传参数:
pict model.txt /o:3 > testcases_3wise.csv
这里的 /o:3 表示 3-wise。生成用例数大约是 Pairwise 的 3~5 倍。
说白了,全组合测试策略的核心是“权衡”。你手上有多少测试时间?目标系统的故障代价有多大?团队能维护多少用例?想清楚这几个问题,再决定用 Pairwise 还是 3-wise。嗯,这就是我多年总结下来最实用的原则。