本发明涉及计算机软件测试领域,设计了一种基于变异体分组的软件变异测试数据进化生成方法。该方法区别于已有方法的特色在于,首先,基于变异体被杀死的可达性条件,将变异体分成若干组,使得每组包含相对较少的变异体;在此基础上,把杀死所有变异体的测试数据生成问题,转化为若干个相对简单的子问题;然后,对于每个子问题,采用一个子种群进行求解;另外,在求解的过程中,随着变异体不断被杀死,对整个优化问题逐步简化,进一步降低问题的求解难度。该方法可以降低变异测试数据生成问题的难度,提高变异测试的效率和可行性,因此,具有重要的理论意义和实用价值。
背景技术:
变异测试是一种面向缺陷的软件测试方法,基本原理是:首先,采用变异算子对被测程序g做微小的合乎语法的变动,称为变异;产生的新程序m称为变异体;然后,基于相同的测试数据x分别运行源程序g和变异体m,并比较二者输出的异同,如果不同,就认为测试数据x将变异体m杀死。
杀死变异体需要具备如下3个条件,分别是可达性、必要性和充分性[1]:
(1)可达性:以x为输入运行g时,能够执行到变异语句s。
(2)感染性:执行变异语句s后,m产生不同于g的状态。
(3)传播性:m与g的输出不同,即m与g在变异语句处产生的不一致状态能够传递到程序的输出。
变异测试常被用于评价现有测试数据集的质量;也被用于辅助生成单元测试数据,其准则为所生成的测试数据集能够杀死所有变异体[2]。对于给定的测试数据集,其杀死的变异体数量占所有非等价变异体数量的百分比,称为该测试数据集的变异得分。变异得分是衡量测试数据集缺陷检测能力的重要指标[3]。
研究结果表明,比起传统的测试方法,基于变异分析生成的测试数据集,往往具有更高的缺陷检测能力。但是,变异测试需要消耗大量计算资源,很难在实际测试中得以应用。如何提高变异测试的效率是值得深入研究的问题[4]。该问题的很好解决,将会为变异测试得到广泛应用扫清障碍,使其得到更好的发展。
为了降低变异测试的复杂度,howden[5]提出弱变异测试的思想。弱变异测试以相同的测试数据作为输入执行原程序和变异体,如果变异语句被执行后,程序中某个中间变量的状态发生了改变,则认为该测试数据杀死了该变异体。本质上,弱变异测试数据生成方法主要关注于满足可达性和感染性条件。实验结果表明,虽然按照弱变异测试准则生成的测试数据不能确保满足充分性条件,但在实证研究中也能取得较高的变异得分。为此,本发明针对花费更小的弱变异测试方法进行研究。
对复杂软件的测试数据生成问题,采用诸如遗传算法等智能优化方法进行求解,以期取得更高的求解效率,是近年来软件工程界一个全新的研究方法,并且取得了很多可喜的研究成果[6]。
使用遗传算法解决变异测试数据生成问题,需要将测试数据生成问题转化为函数优化问题。当变异体的数量很多时,目标函数的个数也会很多,从而建立的模型就是一个超多目标的函数优化问题,求解起来会非常困难。
如果根据变异体能够被杀死的条件,将变异体分为若干组,使得每组包含较少的变异体,就可以大大降低问题的求解难度。鉴于此,本发明研究基于变异体分组的变异测试数据生成问题,并提出基于多种群优化的测试数据进化生成方法。
技术实现要素:
本发明提出一种基于变异体分组的软件变异测试数据进化生成方法。首先,基于变异体被杀死的可达性条件,将变异体分成若干组,使得每组包含相对较少的变异体,这样,就可以把杀死所有变异体的测试数据生成问题,转化为若干相对简单的子问题;然后,采用多种群进化算法对所建立的模型进行求解,每个子种群求解一个子优化问题;在求解的过程中,随着变异体不断被杀死,对整个优化问题逐步进行简化,进一步降低问题的求解难度。
本发明所要解决的技术问题:根据变异体被杀死的可达性条件对变异体的相似性进行描述,将相似程度较高的变异体分为一组,从而把一个包含很多目标的优化问题转化为若干个包含较少目标的子优化问题,有效降低测试数据生成问题的难度;给出一种基于多种群优化的进化算法来求解所建立的模型,包括适应度函数的设计,约束条件的处理等,进一步提高测试数据生成的效率。
本发明的技术解决方案:一种基于变异体分组的软件变异测试数据进化生成方法,其特征包含以下步骤:
步骤1.基于可达性的变异体分组方法。
我们根据变异体被杀死的可达性条件对两个变异体之间的相似性进行描述。分两种情况讨论任意两个变异体mi和mj之间的相似性。
情况一:d(g)中不存在任何从si到sj或者从sj到si的路径。
在这种情况下,任何可以执行其中一条变异语句的测试数据,都不可能执行到另外一条变异语句。换句话说,任何测试数据都不可能将变异体mi和mj同时杀死。因此,我们规定mi和mj的相似度为0。在进行分组时,这样的变异体应该分在不同的小组。
情况二:d(g)中存在从si到sj或者从sj到si的路径。
在这种情况下,有可能存在某个测试数据,能够同时将变异体mi和mj杀死。用γ表示d(g)中所有有向路构成的集合。设:
υ1={p|si∈p且sj∈p,p∈γ}
υ2={p|si∈p或sj∈p,p∈γ}
υ1是既能覆盖si,又能覆盖sj的路径构成的集合;而υ2是能够覆盖si或者覆盖sj的路径构成的集合。定义mi和mj的相似度为:
记所有变异体构成的集合为
我们将r称为
变异体的分组步骤如图1所示。
步骤1:令i=1;
步骤2:从
步骤3:将
步骤5:令
步骤6:如果
图1基于相似度的变异体异体分组方法
最终,可以将
步骤2.测试数据生成问题的数学模型。
考虑第i组变异体
对
设以变量x为输入运行程序时,可以执行到变异条件语句
则
设以变量x为输入运行程序时,不能执行到变异条件语句
另外,因为变异体能够被杀死的首要条件,是变异语句能够被执行,我们可以把测试数据能够执行足够多的变异语句作为该优化问题的约束条件。设测试数据x可以覆盖小组
综上所述,杀死小组
因为共有l小组变异体,杀死所有变异体的测试数据生成问题,可以建模为l个多目标子优化问题,具体形式如下:
该模型共包含l个优化子问题,每个子优化问题又是一个多目标优化问题。这样一来,就可以把一个包含很多目标函数的优化问题,分解为若干个子优化问题,每个子问题包含的目标函数都大大减少,从而降低了问题求解的难度。
步骤3.基于多种群遗传算法的测试数据生成。
基于步骤2建立的优化模型,本部分给出该模型的进化求解方法,以高效生成杀死变异体的测试数据,其特征在于以下步骤:
步骤1:设定算法包含的控制参数值;
步骤2:子种群初始化;
步骤3:计算个体的适应值;
步骤4:判断算法的终止条件是否满足;
步骤5:判断子问题约简条件是否满足;
步骤6:进行选择、交叉,以及变异等遗传操作,产生新的种群;
步骤7:输出结果。
具体实施方式
下面对本发明的实施方式进行详细说明。
步骤1.基于可达性的变异体分组方法。
1.1变异体相似性的度量
在弱变异准则下,变异体被杀死的条件包括可达性和传染性。可达性是指变异语句能够被执行;感染性是指变异语句被执行后,中间变量能够产生不同与原程序的状态。一般情况下,在执行程序之前,感染性条件是否满足是很难判定的,因为中间变量的值需要通过执行程序才能获得。因此,根据变异体被杀死的可达性条件对两个变异体之间的相似性进行描述。而两个语句的可达性条件是否接近,在很大程度上取决于他们在程序中的相对位置。我们可以借助于程序的控制流图对语句的位置关系进行分析。
控制流图(controlflowgraph,cfg)是程序控制结构的图形表示,是一种具有如下结构的有向图d=(n,e,s,e),其中,n的元素称作d的节点,对应程序的某一或几条语句;e的元素eij=(si,sj)称为d的边,表示从节点si到sj存在控制流。每个程序的控制流图还包含惟一的入口节点s和出口节点e。
路径p是指一个节点序列s1,s2,…,sk,满足从节点si到si+1有边存在,i=1,2,…,k-1。
设被测程序为g,其控制流图为d(g)。现在对g中n条语句s1,s2,…,sn(可以重复)实施变异操作,得到的变异体分别记为m1,m2,…,mn。下面分两种情况讨论任意两个变异体mi和mj之间的相似性。
情况一:d(g)中不存在任何从si到sj或者从sj到si的路径。
在这种情况下,任何可以执行其中一条变异语句的测试数据,都不可能执行到另外一条变异语句。换句话说,任何测试数据都不可能将变异体mi和mj同时杀死。因此,我们规定mi和mj的相似度为0。在进行分组时,这样的变异体应该分在不同的小组。
情况二:d(g)中存在从si到sj或者从sj到si的路径。
在这种情况下,有可能存在某个测试数据,能够同时将变异体mi和mj杀死。用γ表示d(g)中所有有向路构成的集合。设:
υ1={p|si∈p且sj∈p,p∈γ}
υ2={p|si∈p或sj∈p,p∈γ}
υ1是既能覆盖si,又能覆盖sj的路径构成的集合;而υ2是能够覆盖si或者覆盖sj的路径构成的集合。定义mi和mj的相似度为:
其中,|υ1|和|υ2|分别表示集合υ1和υ2包含的路径条数。由于
记所有变异体构成的集合为
我们将r称为
1.2变异体的分组方法
由定义容易知道,r(mi,mj)∈[0,1],且r(mi,mj)的值越大,变异语句si和sj的可达性条件就越接近。给定一个阈值r0∈(0,1],作为衡量变异体之间相似程度的标准。如果r(mi,mj)的值大于阈值r0,那么,把mj与
步骤1:令i=1;
步骤2:从
步骤3:将
步骤5:令
步骤6:如果
图1基于相似度的变异体异体分组方法
最终,可以将
步骤2.测试数据生成问题的数学模型。
下面给出杀死多个变异体的测试数据生成问题的数学模型。首先,给出每个子优化问题的目标函数;然后,建立子优化问题的约束条件;最后,把若干子优化问题整合为一个大的优化问题。
考虑第i组变异体
对
为了使用进化优化方法求解上述问题,就需要把覆盖变异条件语句
设以变量x为输入运行程序时,可以执行到变异条件语句
则
设以变量x为输入运行程序时,不能执行到变异条件语句
以测试数据x为输入运行插装后的新程序,就可以得到ni个目标函数的函数值,分别记为
另外,因为变异体能够被杀死的首要条件,是变异语句能够被执行,我们可以把测试数据能够执行足够多的变异语句作为该优化问题的约束条件。设测试数据x可以覆盖小组
综上所述,杀死小组
由式(3)可以看出:(1)第i个子优化问题包含的目标函数共有ni个。一般情况下,ni的值比n要小得多。因此,该子优化问题比整个优化问题比起来要简单得多;(2)按照分组的规则,第i个小组的变异体
这样,可以把杀死小组
该模型共包含l个优化子问题,每个子优化问题又是一个多目标优化问题。这样一来,就可以把一个包含很多目标函数的优化问题,分解为若干个子优化问题,每个子问题包含的目标函数都大大减少,从而降低了问题求解的难度。
步骤3.基于多种群遗传算法的测试数据生成。
步骤2将杀死多个变异体的测试数据生成问题,建模为包含多个子问题的优化问题,其中,每个子优化问题包含较少目标函数,每一目标函数对应一个变异体。另外,每个子优化问题包含的目标函数之间具有较大的相似性,从而其最优解也很接近。
下面提出一种多种群并行遗传算法求解上述模型。该算法中,每个子种群通过进化,求解一个子优化问题,从而生成杀死该子优化问题对应变异体的测试数据。有多少个子问题,就采用多少个子种群并行进化。
3.1种群设置
同一个子优化问题包含的目标函数具有很大的相似性,可以采用同一个子种群进行优化。由于建立的模型包含l个子优化问题,共需要l个子种群来对这l个子问题进行优化。设对第i个子问题,建立的子种群为popi。子种群的规模统一设为pop_size。
对每个子优化问题,随机产生pop_size个初始解,构成初始子种群。第i个子种群popi包含的个体记为
3.2进化个体编码
采用遗传算法求解优化问题时,需要采用合适的方法对进化个体编码。这里,一个进化个体就是程序的的一个输入。如果程序的输入为整数,就采用二进制编码;如果程序的输入为实数,就采用实数编码。不失一般性,对个体
3.3进化个体适应值
对第i个子种群的第j个进化个体为
如果
反之,如果
另外,
此外,第i个子优化问题的约束条件为
当约束条件
基于以上讨论,进化个体
其中,ρ为权重系数。对于第i个子种群,采用式(5)评价进化个体
3.4子优化问题的约简
针对式(4)表示的优化模型,采用某种优化方法进行求解时,不断生成杀死更多变异体的测试数据。这样一来,每组包含的未被杀死的变异体个数不断减少,相应的子优化问题也应该进行必要的约简。
考虑式(3)表示的第i个子优化问题,由于该问题的每个目标函数对应一个变异体,因此,当已经生成杀死该变异体的测试数据时,在保存该测试数据的同时,应该把与之对应的目标函数从式(3)中删除,这时,相应的子优化问题的模型也要进行适当的约简,从而提高测试数据生成的效率。
假设在测试数据生成过程中,
由式(6)容易看出,通过子优化问题的约简,该问题包含的目标函数不断减少,从而使得问题的求解难度不断降低。
如果某个子优化问题的目标函数缩减为0,则把子优化问题从整个优化问题中删除,并终止该子优化问题对应子种群的进化。
3.5算法终止条件
对于每个子优化子问题,相应子种群的进化,有如下两个终止条件:一是该子问题包含的目标函数个数变为0。此时,该子优化问题对应的变异体全部被杀死,生成了所有期望的测试数据;二是子种群进化到设定的最大进化代数。此时,即使没有找到杀死全部变异体的测试数据,算法也将终止运行。这是因为,一方面,如果无限制运行算法,需要的计算量是无法估计的;另外,有些变异体可能是等价变异体,任何测试数据都无法将这些变异体杀死。如果算法无限运行,将永远无法终止。所以,我们会在种群进化到一定代数后,强行终止算法运行。
3.6算法步骤
综上所述,基于多种群优化的测试数据生成方法步骤如下:
步骤1:设定算法包含的控制参数值;
步骤2:子种群初始化,子种群个数与变异体组数相同;
步骤3:以个体为输入运行插装后的被测程序,根据式(5),计算该个体的适应值;
步骤4:判断算法的终止条件是否满足,若是,转步骤7;
步骤5:判断是否满足子问题约简条件,若是,保存相应的测试数据,将相应的目标函数在目标函数集中删除;
步骤6:根据进化个体适应值,比较不同进化个体的性能,进行选择、交叉,以及变异等遗传操作,产生新的种群,转步骤3;
步骤7:停止进化,对期望测试数据解码,输出。
参考文献:
[1]acreeat.onmutation[d].atlanta:georgiainstituteoftechnology,1980.
[2]offuttaj.automatictestdatageneration[d].atlanta:georgiainstituteoftechnology,1988.
[3]buddta.mutationanalysisofprogramtestdata[d].newhaven:yaleuniversity,1980.
[4]单锦辉,高友峰,刘明浩,等.一种新的变异测试数据自动生成方法[j].计算机学报,2008,31(6):1025-1034.
[5]howdenwe.weakmutationtestingandcompletenessoftestsets[j].ieeetransactiononsoftwareengineering,1982,8(4):371-379.
[6]hermadii,lokanc,sarkerr.geneticalgorithmbasedpathtesting:challengesandkeyparameters[c]//proceedingsof2010secondwriworldcongressonsoftwareengineering,wuhan,2010:241-244.
[7]papadakism,malevrisn.automaticallyperformingweakmutationwiththeaidofsymbolicexecution,concolictestingandsearch-basedtesting[j].softwarequalityjournal,2011,19(4):691-723.
[8]korelb.automatedsoftwaretestdatageneration[j].ieeetransactiononsoftwareengineering,1990,16(8):870-879.