Тестирование мутаций с помощью Rspec - PullRequest
0 голосов
/ 03 октября 2018

Я пытаюсь выполнить мутационный тест для некоторого кода ruby, используя rspec.Я только изучаю рубин и не знаю, правильно ли я это делаю.Часть кода, который я пытаюсь протестировать:

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

Пока мой набор тестов выглядит так:

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

При запуске rspec мои 3 теста пройдены.Однако, когда я использую тестирование мутаций в этом наборе, я убиваю только 3/343, что не очень хорошо.

1 Ответ

0 голосов
/ 05 октября 2018

Так как ваша цель - разработать набор тестов, адекватный мутациям, неубитые мутанты, по сути, предоставляют руководство для того, что тестировать.В идеале ваш вопрос должен содержать несколько примеров для генерируемых мутантов, которые не уничтожаются вашим набором тестов, чтобы другие могли прокомментировать, как писать тесты, которые убивают их.

Позвольте мне лучше ответить на ваш вопрос с общими рекомендациями и примерами.Я не знаком с конкретным инструментом тестирования мутаций, который вы используете, но в целом вы должны следовать процессу, подобному следующему *:

  1. Выберите мутанта, который не был убит вашим тестомустановить и определить, можно ли его убить (мутант может быть семантически эквивалентен вашей программе - если да, отбросить его из пула мутантов).

  2. Написать тест, который убиваетвыбранный мутант - то есть, напишите тест, который проходит по вашей исходной программе, но не работает на мутанте.

    • Определите подходящие входные данные, которые запускают некорректное поведение, введенное мутантом.
    • Определите подходящего тестового оракула, который утверждает ожидаемое поведение / вывод вашей программы (т. Е. Тестового оракула, который проходит по вашей исходной программе, но не работает с мутантом).

Пожалуйста, имейте в виду, что ваша цель должна не заключаться в написании минимальных тестов, которые просто убивают всех мутантов, а скорее тестов, которые имеют смысл вконтекст вашего проекта и как побочный продукт убивают мутантов.Опять же, если бы вы могли предоставить конкретные примеры для мутантов, которые не убивает ваш набор тестов, я и другие лучше прокомментируем, какие тесты отсутствуют.

Пример: Предположим, у вас есть мутантэто приводит к следующей ошибке (т. е. изменяет реляционный оператор в операторе if вашей исходной программы): - if cipher_letter > @z_offset + if cipher_letter >= @z_offset Чтобы убить этого мутанта, требуется тест, который проверяет граничное условие - то есть тест, который кодирует хотя бы один символк «Z».Ваш текущий набор тестов не имеет такого теста.

* Этот процесс описывает традиционное тестирование мутации.Недавнее исследование [1] , [2] предполагает, что (1) не все убиваемые мутанты должны быть убиты (некоторые мутанты вызывают тесты, которые просто не имеют смысла) и (2)эквивалентные мутанты могут указывать на проблему в вашей программе (например, нежелательную избыточность или неоднозначность), которую вы, возможно, захотите устранить вместо удаления эквивалентного мутанта.

...