王一彻,高建华
(上海师范大学 计算机科学与技术系,上海 200234)
软件可靠性测试是软件开发过程中的一个重要环节,其目的是对软件的可靠性进行验证,判断其是否满足用户的需求。如果得到的可靠性满足需求,则停止可靠性测试,否则,需对软件中的缺陷进行纠正,提高软件产品的可靠性。
基于运行剖面的测试在软件可靠性领域是一种基本的测试方法。传统方法通过调试测试找出系统中导致失效的漏洞,而不考虑实际运行中的失效概率,基于运行剖面的测试则把测试用例的概率,即软件的运行剖面考虑在内,选择在实时运行中导致软件失效的高发生率输入,这些输入对软件可靠性的影响较大,移除这些漏洞可以极大地提高软件可靠性。因此,基于运行剖面的测试可有效提高软件可靠性[3-5],同时,运行剖面测试技术也被广泛应用于软件可靠性的评估中[6-7]。例如,文献[8]将运行剖面测试应用于实时嵌入式软件,文献[9-10]研究了运行剖面测试与Web应用可靠性之间的关系。此外,运行剖面测试还被应用于构件软件系统中[11]。
然而,任何测试选择技术都存在饱和点[12],基于运行剖面的测试也一样,其主要关注高发生率的故障,而当软件需要达到较高的可靠性,即超出了基于运行剖面的测试的临界点时,需要找到低发生率的故障(高发生率导致故障的漏洞已被移除)[13]。因此,基于运行剖面的测试并不适用于需要高可靠性的关键系统中。
文献[6-7]提出一种基于运行剖面的自适应测试策略,通过测试用例的反馈驱动选择进行可靠性评估,将软件测试描述为一个反馈和自适应控制问题,并使用一个受控的马尔科夫链来描述测试过程,以最小化可靠性估计的方差。文献[14]将自适应测试与梯度下降法相结合,其测试结果优于传统的基于运行剖面的测试。文献[15]使用置信区间作为驱动标准自适应地选择测试用例,以更准确地评估软件的可靠性。不同的测试技术可以发现不同的故障,针对这一特点,可以将不同的测试技术相结合,而不是仅使用一种测试方法。文献[16]把运行测试和调试测试结合起来,形成一种混合自适应测试技术,文献[17]将这种混合自适应测试技术应用于软件可靠性的评估。
为了更好地将基于运行剖面的测试技术应用于高可靠性要求的系统,本文提出一种基于运行剖面的测试用例分配和选择方法。该方法在测试用例分配和选择过程中,通过每一次迭代的结果对下一次测试进行动态调整,以提高测试的有效性。
软件测试主要包括以下2个步骤:
1)根据选择标准,从测试集中选取不同的测试用例进行测试。
2)将得到的输出结果与预期结果进行比较,如果不一致,则判定软件发生失效。
本文把引起软件失效的测试用例定义为失效点,程序移除错误可使许多失效点消失,把这些失效点的集合定义为失效域,失效点数量占总执行测试用例数量的比例定义为失效率。设D是待测软件的输入域,T为测试用例集,现作如下假设:
1) 运行剖面的划分依赖于被测试的应用软件[18],测试人员可选择不同的分区标准,如根据功能、结构等进行划分,把输入域D分成m个子域,即测试人员的测试目标可决定分区标准。
2) 假设每个测试用例只能导致失效或成功,即肯定可以得到运行后的实际结果,并能够和预期结果进行比较。
3) 每个测试用例都是独立执行的,相互之间没有影响,即一个导致系统失效的测试用例总是导致失效,而不会被之前执行的测试用例影响。
图1 测试过程
(1)
(2)
其中,ξ是基于采样的估计分布和真实分布之间的误差,1-δ是对这种近似的期望,ρ是在第k次迭代中至少有一个测试用例被执行的子域数,z1-δ是具有显著性水平δ的正态分布,Tk+1即为在k+1次迭代中要执行的测试用例数,具体过程如算法1所示。
算法1测试用例分配算法
for i=1 to m
end for
for i=2 to m
end for
//根据式(2)计算Tk+1
//将测试用例分到每一个子域
i=1;
for j=1 to Tk+1
while rj>bido//找到要分配测试用例的子域
i=i+1;
end while
end for
算法2测试用例选择算法
for r=1 to g
//从Ni中选择h个测试用例放入Gr
Ni=Ni-Gr;
end for
for r=1 to g
end for
综上,本文方法在测试阶段通过每一次迭代的结果对下一次测试进行动态调整,是一种自适应的测试方法。因此,该方法的效率比传统的运行测试方法更高。
为了验证本文方法的有效性,设计实验分析以下问题:
问题1在测试过程中各子域概率的变化情况。
问题2与传统基于运行剖面测试对比的优势。
本文设计实例并对其进行分析,假设按照软件的功能可将其划分为5个子域,表1给出各子域中测试用例的情况。
表1 子域及其测试用例集
对于问题1,虽然子域D2实际的使用概率只有10%,但其在第1次迭代测试中的失效率较高,相应地,该子域的概率向量得到提高,因此,在之后的测试中会对该子域进行更多的测试,而对于上一次迭代没有出现失效点的子域D1和D5,其概率向量有所减少,在接下来的测试中会减少其比例。若使用传统的基于运行剖面的方法对表1给定的实例进行测试,其根据每个子域的运行剖面(即实际使用概率)分配测试,更着重于使用概率大的子域。
对于问题2,传统的基于运行剖面的测试倾向于使用概率较大的子域D3和D4进行更多测试,本文测试会根据前一次迭代的测试结果进行动态调整,当子域D3和D4中的故障被移除后,传统的基于运行剖面测试将难以继续提高系统的可靠性,而本文测试将把测试重心转移到那些使用概率较低而失效率较高的子域上,移除其中的故障后可进一步提高系统的可靠性,因此,本文测试方法相比于传统基于运行剖面的测试具有一定优势。
本文提出一种基于运行剖面的测试用例分配和选择方法。采用自适应的学习方法,根据每次迭代的结果动态调整下一次测试。当高发生率的故障被移除后继续聚焦低发生率故障,以提高软件的可靠性。实例分析结果验证了该方法的有效性。然而,本文仅给出测试方法有效性的简单分析,下一步将进行大量实验验证,并对相关定义与假设部分提出的假设进行研究,以提高测试的准确性。