Автоматически перезапустить пример rspec, если возникает Timeout :: Error - PullRequest
4 голосов
/ 25 октября 2011

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

Я получаю случайные Timeout::Error исключения в некоторых моих тестах, и я хотел бы иметь возможность игнорировать их и автоматически перезапускать пример. О сбое следует сообщать только после 10 неудачных попыток.

О любых других исключениях и сбоях следует сообщать.

Я пытался реализовать это поведение, используя глобальный хук around(:each) в spec/spec_helper.rb файле:

RSpec.configure do |config|
  config.around(:each) do |example|
    attempts = 0
    passed = false

    begin
      attempts +=1
      example.run
      passed = true

    rescue Timeout::Error => e
      raise e if attempts >= 10

    end until passed
  end
end

Однако спасательная часть никогда не выполняется при возникновении исключения. Есть идеи почему?

Спасибо! Dorian

P.S. Я использую rspec 2.6.0

Ответы [ 2 ]

7 голосов
/ 03 февраля 2012

Вы не можете спасти исключения в around блоках, потому что они не распространяются.Однако, если вы абсолютно должны повторно выполнить неудачные примеры, вы можете вытолкнуть текущее исключение из @example, как здесь:

https://github.com/jnicklas/capybara/blob/c21d5eb2375b610ac13f54cf240e59c80918a2f1/spec/spec_helper.rb#L16

Это выглядитдовольно противныйНашим оправданием была ошибка в нашей апстрим-библиотеке, но я бы вообще этого избегал, если это вообще возможно.

1 голос
/ 17 июня 2014

Мы использовали ответ @ Jo как способ получить доступ к исключению для ведения журнала.

Это работало для нас прекрасно, пока мы не обновили RSpec до 2.99 (с целью перехода на 3.0).Кажется, что переменная экземпляра @ exception больше не присутствует в объекте example в обходном хуке.

Нам пришлось переключиться на ловушку до и после и получить доступ к исключению, как и раньше, из примера ловушки .

config.after(:each) do |example|
    exception = example.instance_variable_get('@exception')
    # ....
end

Мы не пыталисьповторите попытку, но я не уверен, как вы добьетесь этого в RSpec 3.0.

...