Запуск теста rspec дважды, когда результат стохастический - PullRequest
0 голосов
/ 21 декабря 2018

У меня есть алгоритм, который работает с доверительным пределом 99%.Поэтому, если я настрою тест как этот

let(:valid_input_signal) { randomly_generate_signal_plus_noise }
it { expect(my_detector(valid_input_signal).signal_present?).to be true }

, он провалится 1% времени.Я мог бы написать тест, который запускает my_detector на тысячах действительных входных сигналов и проверить, что он дает сбой только в 1% случаев, но это займет много времени, и цель теста не в том, чтобы проверить, работает ли алгоритм, ане было никаких изменений в коде, который нарушает алгоритм.

Я думаю, что правильным способом для достижения этой цели является запуск вышеуказанного теста во второй раз и, если он пройден, то дать ему проход.Если произойдет сбой во второй раз, то дайте ему сбой, потому что вероятность его двухкратного сбоя при условии, что база верна, равна 1 на 10000.Конечно, это означает, что 1 в 10000 раз объединенный тест не будет выполнен на действительной кодовой базе, но это намного лучше, чем в настоящее время, когда 1 в 100 раз тест не пройден.

Так что есть способrspec сделать это, то есть запустить тест во второй раз, если он не прошел первый раз, и вывести ошибку только в случае сбоя во второй раз?

Ответы [ 2 ]

0 голосов
/ 25 декабря 2018

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

Вы не можете проверить это в случайно сгенерированных входных данных.Допустим, у вас есть набор из 100 valid_input_signals, и он не работает 5-го числа, и это нормально.Кто-то меняет алгоритм, и он начинает проходить 5-го и терпит неудачу 17-го.По-прежнему происходит сбой в 1% случаев, но все ли правильно?

Как продолжить отсюда, не очевидно - это зависит от того, что делает алгоритм.Может быть, вы можете извлечь некоторые части в отдельные компоненты ответственности и протестировать их изолированно?

Но, может быть, это устаревший алгоритм, и вам нужно как можно больше покрыть его спецификациями?Если это так - я бы обменял скорость на покрытие:

Генерация 1000 сигналов и сохранение тех, которые my_detector(valid_input_signal).signal_present? == true, сохранение их в файле или чем-то еще, и запуск спецификации по отношению к этим детерминированным входам.

valid_inputs.each do |input| 
  expect(my_detector(input).signal_present?).to be true
end

Допустим, 10 из сгенерированных дают false, проверяют и подтверждают, что это истинный минус (они предполагают возвращать ложь), сохраняют их в каком-то другом месте и делают для них спецификации какхорошо:

invalid_inputs.each do |input| 
  expect(my_detector(input).signal_present?).to be false
end

Допустим, (после ручной проверки) только 8 из них были истинно отрицательными, 2 левых должны возвращать true, но возвращать false - это могут быть ошибки.Сохраните их на потом.

Довольны ли вы охватом 1000 образцов?Сколько времени нужно, чтобы бежать?Можете ли вы обменять часть этого времени и увеличить охват до 10000 образцов?1 миллион?Это твой выбор.

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

0 голосов
/ 21 декабря 2018

Попробуйте это:

describe '#my_decorator' do
  let(:valid_input_signal_1) { randomly_generate_signal_plus_noise }
  let(:valid_input_signal_2) { randomly_generate_signal_plus_noise }

  it 'should not fail twice in a row' do
    fail unless my_detector(valid_input_signal_1).signal_present? || my_detector(valid_input_signal_2).signal_present?
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...