第一章 覆盖表简介
覆盖表(Covering Arrays),又译覆盖阵列,是组合测试的重要研究领域之一,广泛应用于软件测试、硬件测试、材料测试和测试激素相互作用对基因表达的影响。
1.1 简述覆盖表的作用
软件和硬件的测试在产品的开发过程中扮演着重要的角色,因此软件测试常常在软件开发的过程中耗费大半时间和资源[1]通常情况下,即便是对于简单的软件或是硬件产品,穷举测试也是不可行的,因为可能的测试用例的数量非常巨大。因此需要一个科学有效的测试计划,对待测系统中各参数之间的组合进行有效的测试。这种组合测试需要一种测试用例集生成法,它可以生成少量高质量的测试用例。
根据研究表明,有百分之七十[2]的错误能通过测试每两个参数之间的关系找出。出于对测试用例生成的难度、测试的成本和覆盖强度对覆盖表规模的影响,对任意两个参数之间组合进行完全覆盖的二维覆盖表可以满足大部分的组合测试要求。
举个例子来说,假设我们有一台具有20个开关的原型机,每个开关有"开启"和"关闭"两个状态,我们希望在定型投产之前测试这台原型机。如果穷举的话总共有2^20种可能,全部测试一边显得不切实际而且花费大。在这种情况下我们可以换一种简单一些的方式,我们取一个所有测试用例的子集,在这个子集中任意三个开关之间的2^2种可能的组合都被测试到。这样问题就变成了如何让我们需要的测试用例集最小,这个问题就是覆盖表(Covering Arrays)问题的一个实例。
依照上述实例建模可以得到一个CA(10::2,20,2)的覆盖表,如下图。(具体定义会在下文中介绍)。这个覆盖表规模为10,每两列之间满足全排列。
图1 CA(10:2,20,2)
1.2 现行覆盖表算法
覆盖表的研究已有很长时间,目前有多种求解覆盖表的方法,启发式搜索方法、数学方法和许多种贪心算法,但这些方法都存在各自的局限性,并只能在解决某些特定问题时具有一定的优势。例如:TConfig[3]是一种利用正交表等基本成分进行递归构造的数学方法,该方法具有生成速度快的特点,但不足之处就是需要依赖已有的代数或组合对象。在启发式搜索方面,可以使用禁忌搜索和模拟退火(SA)等方法生成较小的测试用例集,但这些方法一般需要较长的时间.相比之下,启发式贪心算法不仅灵活,而且速度快,目前已经分别提出了 AETG、TCG、DDA和IPO等多种启发式贪心方法,这些方法之间既有区别又有很大的相似性。
下面简单介绍部分贪心算法框架之外的覆盖表生成算法。
1.2.1 Tconfig算法
使用正交拉丁方(orthogonal Latin Squares)的方法,生成双向的组合测试用例集。
设有两个阶数相同(为)的拉丁方阵
,其中将所有放置位置相同的元素组合成一个元组,组合成一个新的矩阵
。 当这个新的矩阵
中每一个元素互不相同,拉丁方阵和是互相正交的。
此时,和即为一对正交拉丁方。 而在阶数固定的情况下,所有两两正交的拉丁方所成的集合称为正交拉丁方族。
此算法利用正交拉丁方的特性,可以下小规模和特定情况下快速生成覆盖表。同样地,此算法因为基于拉丁方的特性不够灵活,不能应对通常情况。
1.2.2爬山算法
爬山、模拟退火和禁忌搜索是用于求解组合优化问题的状态空间搜索技术的变种。有一个一般的优化问题,目的是找到的解决方案是接近最优的。有许多我们已知的解决方案,能使得我们得到从成本上来说最佳的结果,同时,在这些解决方案下的用例集很小。
一个优化问题可以被指定为可行解(或状态)的集合Σ,以及成本C(S)对于每个 S ∈ Σ。最优解对应于具有总体最小成本的可行解。对于每个S ∈ Σ,我们定义了变换集合TS,TS中的每一种变换都可以用来将S变换成另一个可行解S'。通过从TS应用变换,可以从S转换出的相邻解称为S的邻域N(S)。
我们首先随机选择一个初始可行解,然后生成一个随机选择的当前可行解的变换S。如果变换得到一个相等或更低成本的可行解S,则S'被认为是新的当前可行解。如果S'是更高的成本,我们拒绝这个解决方案,并检查另一个随机选择的邻居当前可行的解决方案。这允许我们随机走动,而不降低我们当前解的优点。爬山有可能陷入局部极小(或冻结),因此需要停止启发式。为了增加形成一个好的解决方案的机会,我们重复随机游走(或试验)多次,每次从随机初始可行解开始。
在爬山算法中,当前可行解是一个近似的S覆盖阵列,其中某些T子集没有被覆盖。成本函数是基于未覆盖的T子集的数目,因此覆盖阵列本身将具有零成本。通过选择属于S的k个集合中的一个,然后通过不在k集合中的随机点替换该k个集合中的随机点来进行潜在变换。在爬山试验中,块的数量保持不变。
我们针对最优阵列的大小松弛的上下界,然后通过二分搜索过程在该区间中找到规模最小的覆盖阵列。另一种方法是从已知测试用例集的大小开始并搜索解决方案。当然,使用更少的计算资源,但必须提前知道所需的测试用例集大小。理想情况下,在实际系统中,使用第二种的方法。
1.2.3 禁忌搜索
Tabu搜索通过允许当前可行的解决方案被较差的替代来进行爬山。它限制使用禁忌和指定表的变化。第一是禁止被认为缺乏价值的操作,比如倒转刚刚做的操作。其次是分配更高的权重来实现期望的性能。NurMela[4]使用Tabu搜索描述了许多成功的搜索案例。
1.2.4 模拟退火
Nurmela 和 Osterg˚ard[5],[6]采用模拟退火方法,构造了与覆盖阵列非常相似的覆盖设计。Stevens〔7〕、Stardom〔8〕、科恩及其同事〔9〕将模拟退火应用于覆盖阵列的搜索。
模拟退火使用与爬山相同的方法,但允许算法以受控的概率进行选择,从而降低当前解决方案的质量。这个算法的思路就是在进行搜索的同时避免陷入坏的情况导致卡死。如果变换得到了较高成本的可行解S`,则在exp(−(c(S′)−c(S))/KBT)的概率下S`是可以接受的,其中T是控制模拟的温度,KB是一个常数。
在这个温度下,通过在每个温度下通过一系列跃迁(或马尔可夫链),允许系统在每个步骤中接近"平衡"。通常这是通过设置t:=αt来完成的,其中α(控制减量)是实数小于1。在满足适当的停止条件之后,将当前可行解作为对手头问题的解的近似。再次,我们通过多次试验来提高获得良好解决方案的机会。
1.2.5 Great Deluge 算法
另一种启发式搜索技术被称为great flood[10]或者是 great deluge[11],是threshold accepting算法的一种变种。
这些算法遵循类似于模拟退火的策略,但通常显示更快速的收敛。当成本较高时,不使用概率来决定移动,如果成本小于当前阈值,则选择更差的可行解。这个阈值有时被称为水位,在利润最大化的问题中,水位将上升而不是下降(正如在这种情况下发生的)。随着算法的发展,阈值被降低,使其接近零。这些似乎没有探索覆盖阵列的构造。
1.2.6 遗传算法
在启发式搜索的领域中,遗传算法被证明是有相当竞争力的。其基本的思路是维持一个假定的解决方案的人口,并且由两种操作将人口从一代演变到下一代。突变使假定的解决方案中发生局部局部变化,而交叉组合了一个解决方案的一部分和另一个解决方案的一部分。新一代的生存取决于每一个新推定的解决方案的相对适合度。粗略地说,这决定了如何"接近"到所需的覆盖数组。
第二章 覆盖表的基本定义和应用
2.1 待测系统
待测系统(System Under Testing)是覆盖表服务的对象,系统在此是一个泛指。假定影响SUT的参数有k个,记为F={f1, f2, f3, …. fk},其中参数fi有ai个取值Vi = {0,1,2,3....ai-1},,1≤i≤k。
2.2 覆盖表的定义
记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) |