0


java变异测试(杀死突变体)

java变异测试(杀死突变体)

简介
如果程序产生不同的输出,则测试输入可以区分两个程序
对于这个输入。 变异测试基于一个简单的概念:如果一个测试套件是擅长将我们的程序与其他类似程序区分开来,那么很可能要善于找茬。 这样做的理由是,那么测试可能会被视为试图将程序与某些程序区分开来正确的程序。
给定一个程序 p,一个突变体是某个变体 p’ of p.通常,我们通过应用突变算子来生成突变体:允许我们转换的规则程式。 例如,将算术运算符 + 的出现替换为算术运算符 * 的规则是变异运算符。 其他例如在谓词中将 > 替换为 >=。 通常,我们会产生一个突变体通过仅应用一个运算符的一个实例:此类突变体是一阶的突变体。
仅使用一阶突变体已在两个方面得到证明。 首先,它是认为如果我们的测试发现由一阶突变体定义的微小差异然后它会发现由高阶突变体定义的更大差异:这称为耦合效应。 其次,也有人认为真正的程序员小错误,因此真正的程序就像正确的一阶突变体程序:这被称为称职的程序员假设。 有一些支持这些假设的经验证据,但不可避免地,这些证据是有限的。
只使用一阶突变体的原因是务实的:如果我们不将我们限制在一阶突变体,那么突变体的总数是可能是巨大的。 事实上,即使我们只产生一阶突变体,突变测试工具会产生大量的突变体,即使是一小块代码。 这是限制突变测试采用的因素之一。

生成突变体
我们通常使用突变计算运算符来生成突变体,例如:
(1) replace + by *
(2) replace a variable x, in an expression, by another variable y
(3) replace a variable x, on the LHS of an assignment, by another variable y
(4) deleting a statement.
如果一个突变体可以通过一次应用一个突变算子产生,那么它就是一阶突变体。通常只使用一阶突变体:这限制了生成的突变体的数量。 如果一个突变体不是一阶突变体,那么它就是一个高阶突变体耦合效应:如果我们杀死一级突变体,那么我们就会杀死(大多数)高阶突变体
有能力的程序员假设:真实代码接近正确的(因此类似于正确的一级突变体程序)

突变检测术语
我们说测试用例 t 杀死了突变体 p’ of p 如果 p’ 和 p产生不同
给定来自 t 的输入时的输出。 此外,突变体 p’ of p 是等价的
如果没有测试输入杀死 p’. (p’ of p 在句法上与 p 不同)

在突变测试中,我们产生了程序 p 的一组 M 个突变体。 如果每个突变体都被 T 杀死,则认为测试套件 T 是足够的:对于每个(非等价的)突变体 p’在 M 中,T 中有一些测试用例 t 杀死了 p’. 突变覆盖率是被杀死的非等价突变体的百分比通过 T. 我们的目标是生成一个达到 100% 覆盖率的测试套件; 那个满足相应的充分性标准。

寻找杀死突变体的测试输入
假设我们在语句 s 处对程序 p 进行了变异以形成变异体 p’。 然后为了让测试输入杀死 p’,它必须实现以下目标;
• 执行p’ 的语句s。
• 感染状态:让 s 处的突变/变化导致某些变量 v 的值有所不同(可能是程序指针,代表条件的不同值)。
• 将对v 值的更改传播到输出。考虑以下示例并将其称为p。 其中,input(x) 是一段代码,它接受一个输入并将其分配给 x; output(y) 是一段代码,它输出 y 的值。

1. i n p u t ( x );2. y=1;3. i f ( x>0)4.     x=x ;
    e l s e
5.     x=−x ;6. x=x+1;7. w hil e ( x>0){8.     y=y∗x ;9.     x=x−1;}10. output ( y );

mutate statement 4:

3. i f ( x>0)4.     x=y ;
    e l s e
5.     x=−x ;6. x=x+1;

工具支持
有多种编程语言的工具: For Java, examples include the following(PIT; Major; µJava )
也是一种相对通用的工具,可用于任何具有元模型的语言:
The Wodel tool (and language)

通常产生的突变体数量使得使用工具支持必不可少。 通常,工具至少会执行以下操作:
• 产生突变体。
• 使用给定的测试输入t 运行所有未被杀死的突变体,决定其中哪些被杀死到t。
• 说明哪些突变体尚未被杀死。
工具也可能随机生成测试用例。如前所述,通常可以杀死许多突变体
通过使用随机生成的测试输入。 使这些过程自动化相对简单。 然而,一些突变体更难杀死。 例如,考虑条件 x>c 到 x>=c 的突变,其中 x 是浮点变量。 只有当测试输入将程序带到这个条件并且此时 x 取值 c 时,才有可能杀死这个突变体。 鉴于 x 可以取的大量可能值,可能很难通过随机测试杀死这样的突变体。
因此,通常有一个不是自动化的最后阶段:测试人员考虑尚未被杀死的剩余突变体。 这个最后阶段很昂贵,可能是目前阻止突变测试扩展到大型系统的主要因素。
虽然许多工具都支持突变测试,但有一个“经典”工具:Mothra。 该工具将变异测试应用于 FORTRAN 程序,是第一个重要的变异测试工具。 您会发现有很多突变测试工具 - 尝试一些互联网搜索!

使变异测试更有效
突变测试可能需要付出过多的努力。 即使给定一个小程序,也会产生许多突变体,其中一些是等价的。 之一问题是我们通常会生成和编译许多突变体。 这个问题可以通过生成程序模式来解决:原始程序的参数化版本,其中添加的参数值决定哪些突变被“打开”。
除此之外,还有以下主要方法类别
可以使突变测试更有效:
• 使用更少的突变体。
• 自动识别等效突变体或减少突变体的数量产生了等效的突变体。

研究表明,通过选择标准的适当子集突变算子有可能产生更少的突变体,但(可以说)几乎不会降低这些突变体的有效性。 这种方法称为选择性突变。 还表明,从一组可能的突变体中随机抽样也可能是有效的。
已经提出了许多限制等效突变问题的方法。 其中包括:
• 使用定理证明器等工具来确定是否剩余突变体是等价的。
• 使用依赖性分析等方法来避免产生一些保证是等效突变体的突变体。
• 避免或限制使用产生许多等效突变体的操作符。
• 使用简单的检查。 特别是,发现比较编译后的代码足以消除一些等效的突变体。

模拟突变测试中的其他标准
一些测试标准可能会在突变测试中被模拟:有可能产生
一组突变体,如果我们杀死所有这些突变体,那么我们就满足了正在考虑的标准。 在这里我们将看一个标准:100% statementcoverage。
一个标准的变异运算符用产生错误的新语句替换语句。 因此,为了产生一组突变体来模拟语句覆盖,我们可以执行以下操作:
• 对于程序 p 的每个语句 s,通过替换 s 产生一个突变体 ps
通过产生运行时错误的语句。
• 生成测试以杀死所有非等效突变体。

变异模型
变异测试中的大部分工作都会改变源代码。 然而,人们对变异模型的兴趣越来越大。 显然,如果我们有一个可执行语言的模型,那么我们可以直接使用突变算子、杀死突变体和等效突变体的概念。 我们还获得了类似的测试有效性和充分性度量。有许多潜在的好处。 一、经常生产模型在代码之前,因此模型的变异可能导致在代码生成之前就生成测试。 此类测试用例的早期生成可能会加速软件开发,并有可能提高代码质量。 此外,模型的突变体可能代表相当不同的故障类别,因此终止此类突变体的测试用例可能会发现为终止代码而生成的测试用例未发现的故障。


本文转载自: https://blog.csdn.net/kirsten111111/article/details/129722562
版权归原作者 the only KIrsTEN 所有, 如有侵权,请联系我们删除。

“java变异测试(杀死突变体)”的评论:

还没有评论