Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automatically re-run rspec example if a Timeout::Error occurs

First of all I agree that mocking external API calls is the right thing to do most of the times. However not in this case.

I'm getting random Timeout::Error exceptions in some of my tests and I would like to be able to ignore them and automatically re-run the example. Failure should be reported only after 10 unsuccessful attempts.

Any other exceptions & failures should be reported.

I've tried to implement this behavior using a global around(:each) hook in spec/spec_helper.rb file:

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

However the rescue part never gets executed when an exception occurs. Any idea why?

Thanks! Dorian

P.S. I'm using rspec 2.6.0

like image 543
Dorian Avatar asked Feb 23 '23 14:02

Dorian


1 Answers

You cannot rescue exceptions in around blocks because they do not propagate. However, if you absolutely must re-run failing examples, you can pry the current exception out of @example, like here:

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

It looks pretty nasty. Our excuse was a bug in our upstream library, but I would generally avoid this if at all possible.

like image 146
Jo Liss Avatar answered Apr 26 '23 07:04

Jo Liss