简体   繁体   English

使用Rspec进行突变测试

[英]Mutation Testing with Rspec

I'm attempting to perform a mutation-test on some ruby code using rspec. 我正在尝试使用rspec对某些红宝石代码执行变异测试。 I am just learning ruby and I don't really know if I'm doing it right. 我只是在学习红宝石,我真的不知道我是否做得对。 Part of the code I'm trying to test is: 我要测试的部分代码是:

class Cipher

 def initialize()
  @a_offset = 65 #'A'.unpack('C').first
  @z_offset = 90 #'Z'.unpack('C').first
 end

 def encode(key, plain_text)
  key_offset = key.upcase.unpack('C').first

  cipher_text = plain_text.upcase.split('').collect do |letter| 
   cipher_letter = (letter.unpack('C').first + key_offset - @a_offset)
   if cipher_letter > @z_offset
    cipher_letter -= ( @z_offset - @a_offset + 1 )
   end
   cipher_letter.chr
 end

 return cipher_text.join
end

So far my test suite looks like this: 到目前为止,我的测试套件如下所示:

require 'rspec'
require 'Cipher'

describe "#initialize" do 
   it "should have correct @a_offset" do
     encoder = Cipher.new()
     expect(encoder.instance_variable_get(:@a_offset)).to eq 65
   end 

   it "should have correct @z_offset" do
     encoder = Cipher.new()
     expect(encoder.instance_variable_get(:@z_offset)).to eq 90
   end
 end 

describe "#encode" do
   it "It should correctly encode Caesar with key = A"do
     encoder = Cipher.new()
     expect(encoder.encode('R', 'CAESAR')).to eq ("TRVJRI")
   end 
end

When running rspec my 3 tests pass. 运行rspec时,我的3个测试通过了。 However when I use mutation testing on this suite I only kill 3/343 which is not very good. 但是,当我在此套件上使用突变测试时,我只会杀死3/343,这不是很好。

Since your goal is to develop a mutation-adequate test suite, the unkilled mutants essentially provide guidance for what to test for. 由于您的目标是开发一个足够突变的测试套件,因此,未经杀灭的突变体实质上可以为要测试的内容提供指导。 Ideally, your question should have provided some examples for generated mutants that are not killed by your test suite so that others can comment on how to write tests that kill them. 理想情况下,您的问题应该为未由测试套件杀死的生成突变体提供一些示例,以便其他人可以评论如何编写可杀死它们的测试。

Let me try to best answer your question with general recommendations and examples. 让我尝试通过一般建议和示例来最好地回答您的问题。 I am not familiar with the particular mutation testing tool you are using, but in general you should follow a process similar to the following*: 我不熟悉您使用的特定突变测试工具,但通常应该遵循与以下类似的过程*:

  1. Select a mutant that is not killed by your test suite and determine whether it can be killed (a mutant might be semantically equivalent to your program -- if so, discard it from the pool of mutants). 选择一个没有被您的测试套件杀死的突变体,然后确定它是否可以被杀死(一个突变体在语义上可能与您的程序等效-如果可以,请将其从突变体池中丢弃)。

  2. Write a test that kills the selected mutant -- that is, write a test that passes on your original program but fails on the mutant. 编写杀死所选突变体的测试-也就是说,编写通过原始程序但对该突变体失败的测试。

    • Determine suitable inputs that trigger the faulty behavior, introduced by the mutant. 确定由突变体引入的触发错误行为的合适输入。
    • Determine a suitable test oracle that asserts on the expected behavior/output of your program (ie, a test oracle that passes on your original program but fails on the mutant). 确定一个可以对程序的预期行为/输出进行断言的合适的测试Oracle(即,通过原始程序但在突变体上失败的测试Oracle)。

Please keep in mind that your goal should not be to write minimal tests that simply kill all mutants, but rather tests that make sense in the context of your project and as a byproduct kill the mutants. 请记住,你的目标应该是写最小的测试,简单地杀死所有的突变体,而是测试,在项目的上下文中有意义的和作为副产品杀死突变体。 Again, if you could provide some concrete examples for mutants that your test suite does not kill, I and others can better comment on what tests are missing. 同样,如果您可以提供一些测试示例不会杀死的突变体的具体示例,那么我和其他人可以更好地评论缺少的测试。

Example: Suppose you have a mutant that introduces the following fault (ie, changes the relational operator in the if statement of your original program): - if cipher_letter > @z_offset + if cipher_letter >= @z_offset Killing this mutant requires a test that checks for the boundary condition -- that is, a test that encodes at least one character to a 'Z'. 示例:假设您有一个引入以下错误的突变体(即,在原始程序的if语句中更改了关系运算符): - if cipher_letter > @z_offset + if cipher_letter >= @z_offset杀死该突变体需要进行测试,以检查边界条件-即将至少一个字符编码为“ Z”的测试。 Your current test suite does not have such a test. 您当前的测试套件没有这样的测试。

*This process describes traditional mutation testing. *此过程描述了传统的变异测试。 Recent research [1] , [2] suggests that (1) not all killable mutants should be killed (some mutants elicit tests that simply don't make sense) and (2) equivalent mutants may indicate a problem in your program (eg, unwanted redundancy or ambiguity) that you might want to fix instead of discarding the equivalent mutant. 最近的研究[1][2]建议(1)并非所有可杀死的突变体都应被杀死(某些突变体引发了根本没有意义的测试),并且(2)等效突变体可能表明程序中存在问题(例如,您可能要修复而不是丢弃等效变体的多余冗余或歧义)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM