Есть ли хороший способ отладки зависимых от порядка тестовых сбоев в RSpec (RSpec2)? - PullRequest
14 голосов
/ 10 мая 2011

Слишком часто люди пишут тесты, которые не убираются после них, когда они связываются с состоянием. Часто это не имеет значения, поскольку объекты, как правило, разрушаются и воссоздаются для большинства тестов, но есть некоторые прискорбные случаи, когда существует глобальное состояние объектов, сохраняющееся в течение всего запуска теста, и когда вы запускаете тесты, которые зависят и изменяются это глобальное состояние, в определенном порядке, они терпят неудачу.

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

rspec test1_spec.rb test2_spec.rb # failures in test2
rspec test2_spec.rb test1_spec.rb # no failures

В RSpec 1 было некоторые опции (--reverse, --loadby) для упорядочивания тестовых прогонов, но они исчезли в RSpec 2 и были минимально полезны при отладке. эти проблемы в любом случае.

Я не уверен в порядке, который по умолчанию используют RSpec 1 или RSpec 2, но один специально разработанный набор тестов, который я использовал в прошлом, случайным образом упорядочивал тесты при каждом запуске, чтобы эти сбои обнаруживались быстрее. В результатах теста семя, которое использовалось для определения порядка, было напечатано с результатами, чтобы было легко воспроизвести сбои, даже если вам нужно было поработать, чтобы сузить отдельные тесты в наборе, которые их вызывали. Затем были опции, которые позволяли вам запускать и останавливать любой заданный тестовый файл в порядке, что позволяло вам легко выполнять бинарный поиск для поиска проблемных тестов.

Я не нашел таких утилит в RSpec, поэтому я спрашиваю здесь: какие есть хорошие способы отладки этих типов зависимых от порядка тестовых сбоев?

Ответы [ 7 ]

10 голосов
/ 26 июля 2016

Теперь есть флаг --bisect, который найдет минимальный набор тестов для запуска для воспроизведения ошибки.Попробуйте:

$ rspec --bisect=verbose

Также может быть полезно использовать флаг --fail-fast.

5 голосов
/ 19 мая 2011

Я бы не сказал, что у меня есть хороший ответ, и я бы хотел найти здесь несколько лучших решений, чем мое. Тем не менее ...

Единственный реальный метод, который я имею для отладки этих проблем, - это добавление глобального (через spec_helper) хука для печати некоторого аспекта состояния базы данных (мой обычный виновник) до и после каждого теста (при условии проверки, волнует ли меня это или нет). Недавним примером было добавление чего-то вроде этого в мой spec_helper.rb.

Spec::Runner.configure do |config|
  config.before(:each) do
    $label_count = Label.count
  end

  config.after(:each) do
    label_diff = Label.count - $label_count
    $label_count = Label.count
    puts "#{self.class.description} #{description} altered label count by #{label_diff}" if label_diff != 0
  end
end
1 голос
/ 27 октября 2015

Нашел свой вопрос 4 года спустя, и теперь rspec имеет флаг --order, который позволяет вам устанавливать случайный порядок, и если вы получаете ошибки, зависящие от порядка, воспроизводите порядок с --seed 123, где начальное число распечатывается в каждой спецификации. бежать.

https://www.relishapp.com/rspec/rspec-core/v/2-13/docs/command-line/order-new-in-rspec-core-2-8

1 голос
/ 04 июля 2014

Вот некоторый быстрый грязный скрипт, который я написал для отладки сбоя, зависящего от порядка - https://gist.github.com/biomancer/ddf59bd841dbf0c448f7

Он состоит из 2 частей.

Первый предназначен для многократного запуска rspec suit с разными начальными значениями и вывода результатов в файлы rspec_[ok|fail]_[seed].txt в текущем каталоге для сбора статистики.

Вторая часть перебирает все эти файлы, извлекает имена групп тестов и анализирует их положение в затронутом тесте, чтобы сделать предположения о зависимостях, и формирует некоторые группы «риска» - безопасные, небезопасные и т. Д. Выходные данные сценария объясняют другие детали. и групповые значения.

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

1 голос
/ 26 мая 2011

У нас есть один тест в нашей настройке Continuous Integration, который переносит каталог spec / приложения Rails и запускает каждый из них друг против друга.таким образом.

0 голосов
/ 23 сентября 2014

Rspec Search and Destroy

предназначен для решения этой проблемы.

https://github.com/shepmaster/rspec-search-and-destroy

0 голосов
/ 10 июня 2013

Скорее всего, некоторое состояние сохраняется между тестами, поэтому убедитесь, что ваша база данных и любые другие хранилища данных (включая класс var и globals) сбрасываются после каждого теста. Может помочь database_cleaner .

...