组合测试简介
组合测试(Combinatorial Test)是一种测试用例生成方法。它是将被测系统抽象出来的变量的取值进行组合并生成一组测试用例的过程,它将被测试应用抽象为一个受到多个因素影响的系统,其中每个因素的取值是离散且有限的。多因素(N- way,N>2)组合测试可以覆盖任意N个因素的所有取值组合,在理论上可以发现由N个因素共同作用引发的缺陷。
配对测试(pairwise)它可以根据你设定的条件,自动生成在测试效率和测试覆盖率之间做出平衡的组合,由于两因素组合 测试在测试用例个数和错误检测能力上达到了较好的平衡,它是目前主流的组合测试方法。
pairwise算法
Pairwise是L. L. Thurstone(29 May1887 – 30 September 1955)在1927年首先提出来的。他是美国的一位心理统计学家。Pairwise也正是基于数学统计和对传统的正交分析法进行优化后得到的产物。
Pairwise基于如下2个假设:
(1)每一个维度都是正交的,即每一个维度互相都没有交集。
(2)根据数学统计分析,73%的缺陷(单因子是35%,双因子是38%)是由单因子或2个因子相互作用产生的。19%的缺陷是由3个因子相互作用产生的。因此,pairwise基于覆盖所有2因子的交互作用产生的用例集合性价比最高而产生的。
那么我们选择比较好的测试组合的原则就是:
- 每个因子的水平值都能被测试到;
- 任意两个因子的各个水平值组合都能被测试到,这就叫配对测试法。
现很多程序都围绕pairwise算法产生,最著名的就是ReduceArray,SmartDesgin和微软的PICT工具,本文主要介绍PICT工具的使用。
PICT(推荐)
PICT工具介绍
PICT的全称是Pairwise Independent Combinatorial Testing tool,它会根据输入而自动给出推荐的测试组合,提高测试效率。是一款免费软件:PICT下载地址。安装以后,有详细的帮助文件PICTHelp.htm。
PICT生成测试用例步骤
1、确认模型文件(Model File)
在txt文件中,确认所有影响因子及各因子的可配置值,如下:
升级类型:关机,立即-推迟 设备数据:保存,不保存 是否强制升级:是,否 客户端环境:关机,重启,断电,断网
注意:冒号前是因素名,后面是可取值,冒号和逗号均使用英文标点
2、运行PICT工具生成用例
在命令行上运行"pict.exe picta.txt > pictb.xls"所生成的文件pictb.xls是两因素组合测试用例集,其内容如下:
升级类型 |
设备数据 |
是否强制升级 |
客户端环境 |
关机 |
保存 |
否 |
重启 |
关机 |
不保存 |
是 |
断电 |
立即 |
不保存 |
否 |
断电 |
立即 |
保存 |
是 |
重启 |
关机 |
不保存 |
否 |
断网 |
立即 |
保存 |
是 |
关机 |
推迟 |
保存 |
是 |
断网 |
关机 |
不保存 |
否 |
关机 |
推迟 |
不保存 |
否 |
关机 |
推迟 |
保存 |
是 |
断电 |
立即 |
不保存 |
是 |
断网 |
推迟 |
不保存 |
是 |
重启 |
可见,使用PICT生成组合测试用例非常方便,测试者可以轻松地理解并修改,测试工具可以方便地解析并运行,另外,也可以定义输出的文件为其他格式文件,如:txt文件、word文件。
3、结合实际场景对用例进行分析修正
根据实际模块进行分析
PICT的其他高级应用
1、PICT参数介绍
在cmd中输入pict后,会弹出参数界面,如下:
Options: /o:N:指定“完全覆盖”的维度(参数个数),默认2 /d:C:模型文件的参数分隔符,默认为为分号 /a:C:用于指定别名(alias)的分隔符 ,默认: | /n:C:表示非法值得的前缀,默认~ /e:file:定义随机种子文件(File with seeding rows) /r[:N]: 定义随机种子 (Randomize generation, N – seed) /c :指定模型计算是大小写敏感(默认不敏感)(Case-sensitive model evaluation) /s :显示模型的统计信息(Show model statistics)
2、定义模型文件中各因素的约束关系
在组合测试的基础理论中,各个因素的取值是相互独立的,即因素A的取值不会影响因素B的取值。但是,大多数被测试应用的因素之间存在约束关系。
以上述升级测试为例,当因素【升级类型】的取值是【立即】时,因素【客户端环境】不可能取值【关机】、【重启】,因为选择立即升级后,就开始升级了,用户不可能手动去进行关机和重启操作
如果不考虑约束关系,可以在生成用例后,删除无效的用例即可,但是这样会导致最终的测试用例集不能实现两因素或多因素组合覆盖,如上的例子:
升级类型 |
设备数据 |
是否强制升级 |
客户端环境 |
关机 |
保存 |
否 |
重启 |
关机 |
不保存 |
是 |
断电 |
立即 |
不保存 |
否 |
断电 |
立即 |
保存 |
是 |
重启 |
关机 |
不保存 |
否 |
断网 |
立即 |
保存 |
是 |
关机 |
推迟 |
保存 |
是 |
断网 |
关机 |
不保存 |
否 |
关机 |
推迟 |
不保存 |
否 |
关机 |
推迟 |
保存 |
是 |
断电 |
立即 |
不保存 |
是 |
断网 |
推迟 |
不保存 |
是 |
重启 |
假如直接在用例中删除上述两个不可能的组合,则:关机与保存没有覆盖,是不合理的,所以最好在生成测试用例时由工具来过滤。
在PICT的模型文件中,加入如下的约束(Contraint)语句,就可以定义出因素之间的约束关系。
IF [升级类型] = "立即" THEN [客户端环境] <> "重启"; IF [升级类型] = "立即" THEN [客户端环境] <> "关机";
修改后的模型文件如下:
升级类型:关机,立即-推迟 设备数据:保存,不保存 是否强制升级:是,否 客户端环境:关机,重启,断电,断网 IF [升级类型] = "立即" THEN [客户端环境] <> "重启"; IF [升级类型] = "立即" THEN [客户端环境] <> "关机";
根据修改后的模型文件,生成的测试用例如下:
升级类型 |
设备数据 |
是否强制升级 |
客户端环境 |
推迟 |
保存 |
否 |
断网 |
关机 |
不保存 |
是 |
断网 |
立即 |
不保存 |
否 |
断电 |
推迟 |
不保存 |
是 |
关机 |
立即 |
保存 |
是 |
断网 |
关机 |
保存 |
否 |
重启 |
推迟 |
不保存 |
是 |
重启 |
关机 |
保存 |
否 |
关机 |
关机 |
保存 |
是 |
断电 |
推迟 |
不保存 |
否 |
断电 |
可以看出上述的关机与保存没有覆盖的问题,在新的用例里已经解决了。
3、多因素组合测试
前面pairwise算法中有介绍了:根据数学统计分析,73%的缺陷(单因子是35%,双因子是38%)是由单因子或2个因子相互作用产生的。19%的缺陷是由3个因子相互作用产生的。也就是说:按照配对测试法,有27%的缺陷会被遗漏。
而且在全覆盖与效率之间的取舍,也要根据所测对象来判断,如果测试的是医疗设备,那么更应该保证全覆盖,而不是考虑效率。
接下来介绍如何PICT,生成多因素组合用例,有两种方法
方法一:命令行增加参数
在命令行上使用参数"/o:N"。例如,在命令行上执行"pict.exe picta.txt /o:3",就可以生成三因素组合测试用例集。
方法二:定义子模型
在PICT的帮助文件中有如下的模型文件定义。
PLATFORM: x86, ia64, amd64 CPUS: Single, Dual, Quad RAM: 128MB, 1GB, 4GB, 64GB HDD:SCSI, IDE OS: NT4, Win2K, WinXP, Win2K3 IE: 4.0, 5.0, 5.5, 6.0 APP: SQLServer, Exchange, Office { PLATFORM, CPUS, RAM, HDD } @ 3 { OS, IE } @ 2
根据该模型文件,PICT将对PLATFORM, CPUS, RAM, HDD实施3因素组合覆盖,具体的生成策略可参加下图。PICT在两因素组合覆盖的基础上,对某些因素实施多因素组合覆盖,这有助于实现更灵活的测试策略。
4、考虑在回归测试中引入随机种子
如果每次都使用相同的测试用例,测试用例可能只是反复执行相同的路径,覆盖相同的状态空间,也许不能发现隐藏的缺陷。
如果在测试对象和测试需求不变的情况下,每次都用新的测试用例,随着回归次数的增长,测试执行可以执行更多的路径,发现隐藏缺陷的概率也会提高,在PICT中,随机种子的作用就在于此。
在PICT中,参数"/r[:N]"可以为测试用例生成引入随机种子(N是作为随机种子的整数),以生成不同的测试用例,如下:
pict picta.txt /r:6 pict picta.txt /r:8
上述两个命令生成的用例均可以满足两因素覆盖的要求,且两次用例不一样。
5、卫哨语句
许多软件用卫哨语句来“过滤”无效的输入。例如,在如下代码中,if语句会“过滤”掉所有A<=0的输入。
int func(int A, int B, int C) {if (A <= 0) return ERROR; ... }
如果不读代码,没有仔细分析规格说明,可能会制定如下的模型文件。在该模型中,A的取值是-1, 0, 1。
A: -1, 0, 1 B: -1, 0, 1 C: -1, 0, 1
利用上述模型,所生成的测试用例集包含9条测试用例。
A B C 0 1 -1 1 -1 1 -1 0 -1 1 1 0 -1 -1 0 0 0 1 1 -1 - 1 -1 1 1 0 -1 0 1 0 0
在这9条测试用例中,有6条测试用例会被if语句过滤掉,因为其中A<=0。只有3条测试用例,能够执行后续逻辑,这意味着只有1/3的B和C的取值组合被真正地覆盖。这个例子表明,如果忽视了卫哨语句对执行流的中断,组合测试用例集将不能达成两因素或多因素覆盖的目标 。
方法一:人为修改模型文件
面对此类问题,测试人员要仔细阅读规格说明或源代码,发现会导致执行流中断的“负面”(Negative)取值。将负面取值从模型中排除,将因素的取值置于正常执行流的范围。例如,对于上述被测试函数func,将模型文件定义为:
A: 1, 10, 100 B: -1, 0, 1 C: -1, 0, 1
在生成测试用例集之后,再加入一条的测试用例(A: 0,B: 0, C: 0)。原模型生成的测试用例可以“通过”卫哨语句,覆盖因素A、B、C的两两取值组合;附加的测试用例可以覆盖卫哨语句的“过滤”功能。
方法二:用参数由PICT判断自动过滤
在PICT的模型中,用特殊符号"~"标记出非法(invalid)值(该符号可以自定义,具体见PICT参数介绍)。例如,在如下模型中,参数A的取值0被标记为非法。
A: ~0, 1, 10 B: -1, 0, 1 C: -1, 0, 1
PICT会保证所有有效值的取值组合都会被覆盖,此外任意非法值与有效值的组合也会被覆盖。以上模型将生成如下测试用例集,共12条。
A B C 1 1 -1 1 0 1 10 -1 -1 1 -1 0 10 0 -1 10 -1 1 10 0 0 10 1 0 1 1 1 ~0 0 -1 ~0 -1 0 ~0 1 1
如果很清楚被测试对象的实现逻辑,使用第一种方法可以生成规模较小的测试用例集,因为它几乎不考虑非法值与有效值的组合。如果只是从规格说明中了解到程序可能存在卫哨语句,那么用第二种方法可以生成更“安全”的测试用例集。
图形化PICT工具(CVG)(推荐)
CVG (Combinatorial Variation Generator)基于WPF和微软Pairwise开发包的一个开源工具,可以定义组合维度、过滤条件,日常用例编写已经足够,推荐一下。
下载地址:CVG2.0,具体界面如下,点击帮助可查看使用指南,这里就不介绍了
allpair
工具介绍
为了让业界测试人员更能方便的使用全对偶测试法产生的组合测试的测试用例,James Bach使用Perl语言开发了一个allpairs工具:allpairs下载地址
Allpair生成测试用例步骤
1、确认模型文件(Model File)
输入模型文件,该文件与PICT格式不一致,可以先输入到Exce里,再选择而文件——另存为txt文件即可。
升级类型 |
设备数据 |
是否强制升级 |
客户端环境 |
立即 |
保存 |
否 |
关机 |
关机 |
不保存 |
是 |
重启 |
推迟 |
断电 |
||
断网 |
2、运行allpairs工具生成用例
直接将 allpairs 工具下载并解压到某个路径,在 Dos 窗口下运行命令。切换到工具所在路径,输入 allpairs.exe model.txt >TestCase.txt 或者 allpairs a.txt > TestCase.txt 并回车,其中model.txt为模型文件,TestCase.xls为生成的测试用例,可以自定义。
输出的testcase文件包括两部分:
第一部分是测试用例的集合,【pairrings】列说明的是全对偶方法找到的唯一pairrings的数量;
第二部分列出了全组合的所有pair,且显示了这个pair在测试用例列表中出现的次数,及所对应的测试用例的用例号。
3、结合实际场景对用例进行分析修正
根据实际模块进行分析
参考资料
常用的Pairwise工具集:http://www.pairwise.org/tools.asp
深入浅出Pairwise 算法:http://m.blog.csdn.net/blog/aassddff261/42776543
组合测试法中的全对偶测试法:http://www.infoq.com/cn/news/2011/08/combination-test/
实施组合测试:http://www.cnblogs.com/liangshi/archive/2010/07/25/1784666.html
网页详细解释了种子(seeding): http://www.amibugshare.com/pict/help.html
且提供了一个种子文件下载:http://www.amibugshare.com/pict/PICT_Seed_template.txt
什么是卫哨语句?
条件表达式中,2条分支都是正常行为,就应该使用形如if…..else…..的条件表达式;如果某个条件极其罕见,就应该单独检查该条件,并在该条件为真时立刻从函数中返回。这样的单独检查常常被称为“卫哨语句”。