覆盖表(Covering Arrays),又译覆盖阵列,是组合测试的重要研究领域之一,普遍应用于软件测试、硬件测试、材料测试和测试激素相互做用对基因表达的影响。 git
软件和硬件的测试在产品的开发过程当中扮演着重要的角色,所以软件测试经常在软件开发的过程当中耗费大半时间和资源[1]一般状况下,即使是对于简单的软件或是硬件产品,穷举测试也是不可行的,由于可能的测试用例的数量很是巨大。所以须要一个科学有效的测试计划,对待测系统中各参数之间的组合进行有效的测试。这种组合测试须要一种测试用例集生成法,它能够生成少许高质量的测试用例。 算法
根据研究代表,有百分之七十[2]的错误能经过测试每两个参数之间的关系找出。出于对测试用例生成的难度、测试的成本和覆盖强度对覆盖表规模的影响,对任意两个参数之间组合进行彻底覆盖的二维覆盖表能够知足大部分的组合测试要求。 数组
举个例子来讲,假设咱们有一台具备20个开关的原型机,每一个开关有"开启"和"关闭"两个状态,咱们但愿在定型投产以前测试这台原型机。若是穷举的话总共有2^20种可能,所有测试一边显得不切实际并且花费大。在这种状况下咱们能够换一种简单一些的方式,咱们取一个全部测试用例的子集,在这个子集中任意三个开关之间的2^2种可能的组合都被测试到。这样问题就变成了如何让咱们须要的测试用例集最小,这个问题就是覆盖表(Covering Arrays)问题的一个实例。 浏览器
依照上述实例建模能够获得一个CA(10::2,20,2)的覆盖表,以下图。(具体定义会在下文中介绍)。这个覆盖表规模为10,每两列之间知足全排列。 网络
图1 CA(10:2,20,2) app
覆盖表的研究已有很长时间,目前有多种求解覆盖表的方法,启发式搜索方法、数学方法和许多种贪心算法,但这些方法都存在各自的局限性,并只能在解决某些特定问题时具备必定的优点。例如:TConfig[3]是一种利用正交表等基本成分进行递归构造的数学方法,该方法具备生成速度快的特色,但不足之处就是须要依赖已有的代数或组合对象。在启发式搜索方面,可使用禁忌搜索和模拟退火(SA)等方法生成较小的测试用例集,但这些方法通常须要较长的时间.相比之下,启发式贪心算法不只灵活,并且速度快,目前已经分别提出了 AETG、TCG、DDA和IPO等多种启发式贪心方法,这些方法之间既有区别又有很大的类似性。 框架
下面简单介绍部分贪心算法框架以外的覆盖表生成算法。 dom
使用正交拉丁方(orthogonal Latin Squares)的方法,生成双向的组合测试用例集。 函数
设有两个阶数相同(为)的拉丁方阵 工具
,其中将全部放置位置相同的元素组合成一个元组,组合成一个新的矩阵
。 当这个新的矩阵
中每个元素互不相同,拉丁方阵和是互相正交的。
此时,和
即为一对正交拉丁方。 而在阶数固定的状况下,全部两两正交的拉丁方所成的集合称为正交拉丁方族。
此算法利用正交拉丁方的特性,能够下小规模和特定状况下快速生成覆盖表。一样地,此算法由于基于拉丁方的特性不够灵活,不能应对一般状况。
登山、模拟退火和禁忌搜索是用于求解组合优化问题的状态空间搜索技术的变种。有一个通常的优化问题,目的是找到的解决方案是接近最优的。有许多咱们已知的解决方案,能使得咱们获得从成本上来讲最佳的结果,同时,在这些解决方案下的用例集很小。
一个优化问题能够被指定为可行解(或状态)的集合Σ,以及成本C(S)对于每一个 S ∈ Σ。最优解对应于具备整体最小成本的可行解。对于每一个S ∈ Σ,咱们定义了变换集合TS,TS中的每一种变换均可以用来将S变换成另外一个可行解S'。经过从TS应用变换,能够从S转换出的相邻解称为S的邻域N(S)。
咱们首先随机选择一个初始可行解,而后生成一个随机选择的当前可行解的变换S。若是变换获得一个相等或更低成本的可行解S,则S'被认为是新的当前可行解。若是S'是更高的成本,咱们拒绝这个解决方案,并检查另外一个随机选择的邻居当前可行的解决方案。这容许咱们随机走动,而不下降咱们当前解的优势。登山有可能陷入局部极小(或冻结),所以须要中止启发式。为了增长造成一个好的解决方案的机会,咱们重复随机游走(或试验)屡次,每次从随机初始可行解开始。
在登山算法中,当前可行解是一个近似的S覆盖阵列,其中某些T子集没有被覆盖。成本函数是基于未覆盖的T子集的数目,所以覆盖阵列自己将具备零成本。经过选择属于S的k个集合中的一个,而后经过不在k集合中的随机点替换该k个集合中的随机点来进行潜在变换。在登山试验中,块的数量保持不变。
咱们针对最优阵列的大小松弛的上下界,而后经过二分搜索过程在该区间中找到规模最小的覆盖阵列。另外一种方法是从已知测试用例集的大小开始并搜索解决方案。固然,使用更少的计算资源,但必须提早知道所需的测试用例集大小。理想状况下,在实际系统中,使用第二种的方法。
Tabu搜索经过容许当前可行的解决方案被较差的替代来进行登山。它限制使用禁忌和指定表的变化。第一是禁止被认为缺少价值的操做,好比倒转刚刚作的操做。其次是分配更高的权重来实现指望的性能。NurMela[4]使用Tabu搜索描述了许多成功的搜索案例。
Nurmela 和 Osterg˚ard[5],[6]采用模拟退火方法,构造了与覆盖阵列很是类似的覆盖设计。Stevens〔7〕、Stardom〔8〕、科恩及其同事〔9〕将模拟退火应用于覆盖阵列的搜索。
模拟退火使用与登山相同的方法,但容许算法以受控的几率进行选择,从而下降当前解决方案的质量。这个算法的思路就是在进行搜索的同时避免陷入坏的状况致使卡死。若是变换获得了较高成本的可行解S`,则在exp(−(c(S′)−c(S))/KBT)的几率下S`是能够接受的,其中T是控制模拟的温度,KB是一个常数。
在这个温度下,经过在每一个温度下经过一系列跃迁(或马尔可夫链),容许系统在每一个步骤中接近"平衡"。一般这是经过设置t:=αt来完成的,其中α(控制减量)是实数小于1。在知足适当的中止条件以后,将当前可行解做为对手头问题的解的近似。再次,咱们经过屡次试验来提升得到良好解决方案的机会。
另外一种启发式搜索技术被称为great flood[10]或者是 great deluge[11],是threshold accepting算法的一种变种。
这些算法遵循相似于模拟退火的策略,但一般显示更快速的收敛。当成本较高时,不使用几率来决定移动,若是成本小于当前阈值,则选择更差的可行解。这个阈值有时被称为水位,在利润最大化的问题中,水位将上升而不是降低(正如在这种状况下发生的)。随着算法的发展,阈值被下降,使其接近零。这些彷佛没有探索覆盖阵列的构造。
在启发式搜索的领域中,遗传算法被证实是有至关竞争力的。其基本的思路是维持一个假定的解决方案的人口,而且由两种操做将人口从一代演变到下一代。突变使假定的解决方案中发生局部局部变化,而交叉组合了一个解决方案的一部分和另外一个解决方案的一部分。新一代的生存取决于每个新推定的解决方案的相对适合度。粗略地说,这决定了如何"接近"到所需的覆盖数组。
待测系统(System Under Testing)是覆盖表服务的对象,系统在此是一个泛指。假定影响SUT的参数有k个,记为F={f1, f2, f3, …. fk},其中参数fi有ai个取值Vi = {0,1,2,3....ai-1},,1≤i≤k。
记SUT 的一条测试用例为k 元组(v1,v2,…,vk)(viVi)。
覆盖表是组合测试的用例集,其定义[12]以下:
待测试系统 SUT 的 t 维覆盖表 CA(N;t,k, (v1,v2,…,vk))(或 CA(N;t,v^k),当 v1=v2=…=vk=v 时)是一个 Nk的数组,其中第 i 列对应第 i 个参数。该参数取值记为 vi,任意 t 个参数造成的 N x t 的子数组中包含了该 t 个参数的全部 t 元组[13],其中,t 为组合覆盖测试的强度。本文中提到的两两组合测试指的是 t=2 的状况,即利用二维覆盖表 CA(N;2,k,(v1,v2,…,vk))进行测试。
下面咱们引入一个例子方便理解定义:
一个网络软件系统,它也许可让用户自定义多种不一样的浏览器(f1),它也能够运行在不一样的操做系统(f2)上, 使用多种不一样的网络链接方式(f3)和打印方式(f4)。若是咱们要测试这个系统(如表2.1)咱们须要这样子的用例:(IE,Windows,LAN,Local)、(Chrome, MacOS, PPP, Networked)。为了测试全部可能的组合,咱们须要3^4,也就是81条测试样例。
表1 网络软件系统的配置
Web Browser |
Operation System |
Connection Type |
Print Config |
IE(0) |
Windows(0) |
LAN(0) |
Local(0) |
Chrome(1) |
MacOS(1) |
PPP(1) |
Networked(1) |
FireFox(2) |
Linux(2) |
ISDN(2) |
Screen(2) |
也许这总共81条测试用例看起来能够接受,可是若是咱们将参数的数量增长到十个的时候,咱们就总共须要测试3 ^ 10 = 59 049个测试用例。
然而,咱们能够保证当咱们测试了全部任意两个参数之间的全排列或是t个参数之间的全排列。在表2.2中,咱们能够只使用9个不一样的测试用例来覆盖如表2.1中所示的每两个参数之间的全排列,在最坏状况下也能用29条测试用例来覆盖全部对[14][15]。成对覆盖的概念已经应用于许多学科,包括医药、农业和制造业[29]。
Kuhn[31]发表了了三个关于软件系统故障的研究报告。它们代表,70%的故障能够发现经过测试全部两路覆盖,而90%的故障能够经过测试全部三路覆盖的相互做用检测。在这些实验检测的系统中,六路覆盖检测能够检测出100%的故障。美国食品安委员会(FDA)以后作过相似实验[30],这些实验发现,实验涉及的109种状况中的97%的缺陷能够经过成对的(两路覆盖)参数设置测试来检测。只有三种状况要求覆盖率高于成对覆盖。
表2 网络软件系统测试用例集
Test No |
Web Browser |
Operation System |
Connection Type |
Memory |
1 |
IE |
Windows |
LAN |
Local |
2 |
Chrome |
MacOS |
LAN |
Networked |
3 |
IE |
MacOS |
PPP |
Screen |
4 |
FireFox |
Linux |
LAN |
Screen |
5 |
IE |
Linux |
ISDN |
Networked |
6 |
Chrome |
Linux |
PPP |
Local |
7 |
FireFox |
Windows |
PPP |
Networked |
8 |
Chrome |
Windows |
ISDN |
Screen |
9 |
FireFox |
Linux |
ISDN |
Local |
覆盖表黑应用在不少领域中,如下是一些例子。[16]
软件测试占据任何软件项目的成本的很大一部分,即使如此仍然会发生喝多故障。事实上,来自美国国家标准与技术研究所(NIST)的2002份报告报告了一个使人担心的结论,即软件测试不足每一年会致使$95亿美圆的成本,并将大量的数据归因于嵌入在硬件中的软件故障[4]。Carroll[2,3]还描述了软件测试不足的成本。近年来,许多政府机构已经开始使用更多的现成商业软件(COTS)。许多机构和企业已在为测试方法努力开发适当的模型,开发适当的覆盖方法,涉及覆盖可靠性和故障检测,并开发自动测试生成器。此外,在测试通讯系统和存储系统中的应用也获得了处理。
每一个组件可能都须要单独的测试和认证;然而,系统故障极可能是因为意外的交互做用而产生的。若是经过集成测试能够防止这些故障的一小部分,这可能会产生重大的经济影响。在使用组件时,咱们最好在系统发布以前测试组件的全部组合,然而,即便在一个中等规模的项目中,测试全部可能的组合所需的测试用例集的大小也是使人望而却步的。
软件组件可能因为异常的交互而产生系统故障。理想状况下,人们应该测试组件的全部可能组合,但实际状况下可能存在大量的组合。所以,成对(pairwise)或T路(t-wise)测试能够测试固定的交互级别,在实践中发现大量的故障。
做为一种折衷方案,能够应用组合设计技术来替代特定的固定级别的交互测试,即成对测试或T-WISE测试。虽然这并不能为咱们提供彻底的覆盖,但在交互测试中发现大量故障是成功的
如今有两个不一样领域正在积极研究的组合设计软件交互测试。正如咱们所见,组合测试研究者致力于构建更高的交互强度的更小的用例集。软件测试团体专一于贪婪搜索算法,在更灵活的框架中建模,使其更紧密地匹配实际测试需求。软件测试人员没法预期掌握软件测试套件生成的每一种技术,甚至没法肯定哪一种可用方法对它们的应用是最好的。虽然这个问题的多维建模方法被发现,但解决方案的范围是有限的。软件交互测试所须要的是一种有用的工具,它们经过单独和统一地使用每种技术来构造测试套件的单1、统一的手段来处理这些技术。
在电路中,输入信号经过算术和逻辑运算相互做用,以产生指望的输出向量。然而,错误仍然可能发生。在硬件交互测试中,可使用覆盖数组来解决这个硬件测试问题。
假设咱们要测试一个有k个输入的电路,在电路内,输入信号经过算术和逻辑运算相互做用,以肯定输出向量。就像测试软件同样,咱们但愿经过一系列的输入向量来判断是否有故障,故障发生在哪里。在这种电路实验中,每一个参数经常只有高电位和低电位两种,根据Dumer[17]的研究,使用二维覆盖表能够方便测试。
有时将材料结合以产生改进的性能,如强度、柔韧性和熔点。一样地,某些组合是有毒的或爆炸性的,必须避免。覆盖表能够帮助设计实验。
Cawse[18]在他的论文中混合物实验的实验方案,采用CA(t,k,2)的覆盖表来验证混合物在不一样环境下的物质特性。
激素影响特定基因的表达,并可能相互做用。虽然并非全部可能的激素组合均可以被检测出来,但它是颇有趣的少许激素之间的相互做用。一样,覆盖表是一个很是合适的建模工具来解决这样
贪心的中心思路就是每次选择一条当前最优的测试样例(是一个k元祖)加入测试用例集[19]。被加入用例集的测试用例集的用例可能从多个候选用例中选出,每一个候选用例均由一组策略生成。因为候选用例生成策略中存在随机值和可变参数,候选用例会有所不一样。
假设待测系统有k个参数,每一个参数fi有Ai个可能的取值,测试用例集合为C。
① 依照参数选择策略选取第i个参数 //决策点1
② 若是有多个参数可选,则采用同序参数选择策略选择第i个参数 //决策点2
③ 给选定的第i个参数按照赋值策略赋值 //决策点3
④ 若是有多个参数可选,则采用同序赋值策略给所选的参数赋值 //决策点4
⑤ 循环步骤①~步骤④,直到全部的参数都被赋值,生成用例T //第4层
⑥ 循环步骤①~步骤⑤Candidates次,生成多个测试用例 //决策点5,第3层
⑦ 选取覆盖未被覆盖对最多的测试用例做为最终的测试用例,加入集合C
⑧ 循环步骤①~步骤⑦,直到参数之间的两两组合都被覆盖为止,获得了覆盖表 //第2层
⑨ 反复执行步骤①~步骤⑦Repeitition次,选择规模最小的做为最终结果 //第1层,决策点6
表3 6个决策点中每一个决策点的具体决策
Reputition count |
Candidate count |
Factor ordering |
Level Select |
Factor tie-breaking |
Level tie-breaking |
A Constant |
A Constant |
Uncovered pairs |
Uncovered pairs |
Uncovered pairs |
Uncovered pairs |
Random |
Random |
Random |
Random |
||
Density |
Density |
Take First |
Take First |
||
Level |
Least Using |
||||
Hybrid |
对于该策略点有如下几种备选算法
(1)随机选择 (Random)
(2)和已肯定参数及待定参数的指望相关,密度聚类(Density peaks Clustering)
(3)选择可与已肯定参数之间存在最多未被覆盖对的参数(Uncovered Pairs)
(4)杂交策略 (Hybrid)
(5)和参数取值数目相关,按照参数取值数目降序排列 (Take First)
赋值策略的目的是所选择的值和已肯定的值组成的对能尽量多的覆盖未被覆盖对。
(1)与所有未被覆盖对的指望相关,密度聚类(Density peaks Clustering)
(2)随机赋值
(3)和已肯定参数组合能产生最多未被覆盖对 (Uncovered Pairs)
在参数选择中可能会出现几个参数有相同优先级的状况。在遇到这种状况时,可采用随机选择、按字典序以及未被覆盖对最多的方法来打破平局。
在赋值策略中可能会出现平局的状况。在遇到这种状况时,可采用随机选择、字典序、最少使用过的值和未被覆盖对最多的值。
由于某些决策点采用随机选择,每轮能够产生几组不一样的用例,在其中选择未被覆盖对最多的加入结果集合C。根据其余决策点决策选择的不一样,备选用例集的最佳数目也会不一样。本文将对于这个决策点设计实验,肯定一个或几个相对优秀的常数做为备选用例集数目。
由于某些决策点的策略是随机的,因此屡次循环能够获得多组不一样的结果,这样得到最优解的几率会增长。然而,重复执行算法天然会增长时间成本,并且在实践中能够发现,当循环次数增长到必定程度时,覆盖表规模也不会减少了。本文将对于这个决策点设计实验,肯定一个或几个相对优秀的常数做为算法循环次数。
在固定的强度下,测试用例数目随着参数数目的增长对数增加。下面咱们以强度t = 2 的状况为例,简要证实对数增加。
定理3.1[19]:存在一个有k个参数的待测系统,每一个参数有L个取值。假定,如今有r条测试用例已经被肯定,未覆盖对的数量为N。那么存在一条新的测试用例能够覆盖至少N/L^2个未覆盖对。
证实:设有一集合
U={ (h, p) | h是一条测试用例,t是h被覆盖的对 }
由于有k个参数,每条测试用例覆盖k ( k – 1 ) / 2个对,因此,U中的每一个h对应k ( k – 1 ) / 2个不一样的p。由于,每一个参数有L个取值,因此,每一个对p出如今集合U里的L ^ ( k – 2 )个不一样的测试用例中。
设V是U的一个子集由(h,p)构成,知足测试用例h不在已选定测试用例集r中,而且对p未被已选中测试用例集覆盖。咱们经过两种不一样的方法计算Card(V)的两种不一样方式,赖桢敏定理3.1。
对于V中任意的(h,p),由于p未被覆盖,因此p没有被已选定的测试样例覆盖。所以,p出如今V中的L ^ ( k – 2 )条不一样的测试用例h中。于是,若是未被覆盖对的总数是N,那么
Card (V) = N * L ^ ( k – 2 )
对于每一个位被选中的测试用例h,设mh是被h新覆盖的对的数量。若h是已选定集r中的某一条,那么mh的值为零。则h在V中出现mh次,所以
Card (V) = SUMh (mh)
如今令m为mh中的最大值,为了证实定理咱们必需要证实m至少为N/L^2。由于可选测试用例的总数是L ^ k,咱们就能够获得如下不等式。
Card (V) = SUMh (mh) <= m * L ^ 2
所以,N * L ^ ( k - 2 ) <= m * L ^ k,即
N / L ^ 2 <= m
咱们已经经过上述步骤证实了定理3.1,那么在算法过程当中确定存在一条测试用例覆盖1 / L ^ 2个剩余对。现设贪心算法选择每条测试用例时覆盖了尽量多的未被覆盖对,N是初始时的为被覆盖对数量,由于存在k个参数,每一个参数有L个取值,那么N = k ( k – 1 ) / 2 * L ^ 2。使用贪心算法当r条测试用例已经被选定以后,剩下的待覆盖对的数量是
N' <= N * (1 – 1 / L ^ 2 ) ^ r
所以,若是r > - log (N) / log ( 1 – 1 / L ^ 2 )则N' < 1那么全部的对都已经被覆盖,
使用近似法log(1 – 1 / L ^ 2) = -1 / L ^ 2,由此咱们能够推导当贪心算法覆盖全部未覆盖对时,
r > L ^ 2 * log(N) >= L ^ 2 * ( log(k ( k – 1 ) / 2) + 2 log(L) )
上述证实代表贪心算法所须要生成的测试样例个数随着k的增大而对数增加,而且和L的二次方正相关。[26]
AETG[19][20][21]算法是已有的一种覆盖表生成贪心算法,其组合是(hybrid,uncovered pairs,—,uncovered pairs,—,50)。在AETG中的同序参数选择策略和算法循环次数能够随意指定。AETG参数选择策略采起的是杂交策略,第一个参数选择了未覆盖对最多的参数,其他参数随机排序。
假设待测系统有k个参数,每一个参数有v个值。如今咱们选择了r个测试样例以后,当咱们在选择第r + 1测试样例时,首先生成CandidateCount个不一样的候选用例,而后从中选择一个覆盖最多未被覆盖对的测试用例。每一个候选测试用例由如下贪心算法选择:
1. 选择一个参数f,这个参数的一个值L在当前未被覆盖对中出现的频率最高。将参数f赋值为L。
2. 令f1 = f,并将剩下的参数乱序排列加入待赋值队列。
3.假设f1到fj已经被赋值,对于1 <= i <= j ,令fi的赋值为vi,而后用以下方法为fj+1选择赋值vj+1。vj+1在全部可选值中与已经赋值的参数组成的未覆盖对最多。
因为候选测试用例依赖于在步骤2中选择的随机顺序,使用不一样的随机种子能够产生不一样的测试集。一个有效的优化是使用50个不一样的随机种子生成50个不一样的测试集,而后选择其中最优的。这样有概率将生成的测试的数量减小十到百分之二十,也有肯定性的构造和可替代的随机算法[25],有时生成更少的测试用例。
DDA[22][23]算法也是目前已有的一种贪心算法,在贪心算法框架下的组合是( density, density, take first, take first, 1, 1 )DDA给全部参数定义了一个密度值,其中没有随机策略,所以DDA是一种肯定性算法。
DDA算法的重点在于Density策略的实现,使用密度公式计算未被覆盖对数量的指望。在此以前咱们先作一些定义,将当前计算参数的密度定义为E,r(i,j) 当前参数i和另外一个参数j以前的未覆盖对数目,定义λ为两参数之间的对数总数。E的计算方法为:
1. 若是两个参数之间存在多个未被覆盖对则
E = ( r(i,j) / λ ^ 2 )
2. 若是只有一个参数有一个取值另外一个参数有多个取值之间存在未被覆盖对,则
E = (r(i,j) / λ ) ^ 2
3. 若是两个参数都只有一个可选赋值,若这两个值组成的对被覆盖则E = 1.0,不然E = 0.0。
TCG[24]与AETG接近,其差别在于它的参数选择策略与AETG的参数选择策略不一样。参数按照参数课选择数目降序排列。值选择策略采用的是杂交策略。