3、穷举测试方法:全组合测试策略归纳总结

说到穷举测试,很多人第一反应就是“不可能”。确实,项目里参数一多,组合数就炸了。我记得刚带团队做嵌入式协议栈测试时,一个配置接口有 6 个参数,每个参数 3~5 个取值,全组合大概 4k 多条用例。团队硬跑了一遍,花了整整两周。后来发现,真正能找到问题的组合其实就那么几十个。

所以全组合测试策略,并不是让你真把全部组合都跑一遍,而是用一套方法找出“最能揭露缺陷的那批组合”。说白了,就是一种有优先级、有取舍的穷举。下面我把这些年积累的几种典型策略梳理一下。

什么是全组合测试策略

全组合策略的核心思想是:“覆盖所有可能影响行为的参数取值组合,但只覆盖你选定范围内的”。它通常包含两个步骤:

  1. 参数筛选 – 从所有输入参数里选出真正重要的,忽略不会引起行为变化的。
  2. 覆盖模型选择 – 决定是两两覆盖(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 硬件工装、实验设计
我的经验: 别一上来就上正交表。正交表虽然用例少,但它对参数取值数量有严格限制。Pairwise 更灵活,而且主流测试工具都支持。

参数筛选:把 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,每一行就是一条测试用例。你只需要把另外的测试数据准备逻辑封装好,直接喂给自动化框架就行。

个人建议: 把 PICT 集成到 CI 流水线里。每次有参数修改,自动重新生成 Pairwise 用例并跑一遍。我在上一家公司这么干之后,回归测试的漏报率降了 40%。

知识体系:从穷举到Pairwise的决策路径

下面这张图帮你把整个选择过程梳理清楚。核心就是三个分支:参数个数、每个参数的值数量、以及你对缺陷风险的容忍度。

全组合策略选择决策树 参数集合 参数个数 ≤ 5? 参数个数 > 5? 每参值数少(≤4) 每参值数多(>4) 全因子 或 静态正交表 覆盖率 100% Pairwise 覆盖率约 95% 每参值数少(≤4) 每参值数多(>4) Pairwise 或 3-wise 覆盖率 90%+ 3-wise 覆盖率 98%+ 关键提示 先做参数筛选(等价类+边界值) 再从树上选路径,最后用工具生成用例

工具与自动化集成

除了 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 倍。

注意: 别把 N-wise 当万金油。N 越大,用例数量指数增长,却只覆盖了极少的新交互。我见过有人用 5-wise,生成 8000 条用例,最后找出来的 bug 全都是等价类划分本身就漏了的。浪费。

说白了,全组合测试策略的核心是“权衡”。你手上有多少测试时间?目标系统的故障代价有多大?团队能维护多少用例?想清楚这几个问题,再决定用 Pairwise 还是 3-wise。嗯,这就是我多年总结下来最实用的原则。