Automatically rerun rspec example if timeout occurs :: Error

First of all, I agree that funny external API calls are the right thing to do most of the time. However, not in this case.

I get 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 failed attempts.

All other exceptions and failures should be reported.

I tried to implement this behavior using the global around(:each) hook in the 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 

However, the rescue part never starts when an exception occurs. Any idea why?

Thanks! Dorian

PS I am using rspec 2.6.0

+4
source share
2 answers

You cannot save exceptions in around blocks because they are not propagated. However, if you absolutely must re-run unsuccessful examples, you can subtract the current exception from @example , as here:

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

It looks pretty unpleasant. Our excuse was a mistake in our upstream library, but I would have avoided it at all, if at all possible.

+7
source

We used @Jo's answer as a way to access the exception for logging.

It did a great job for us until we upgraded RSpec to 2.99 (with the goal of moving to 3.0). It seems that the instance @exception variable is no longer present in the example object in a circular hook.

We had to switch to a before and after the hook and access the exception, as before, from the example after the hook.

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

We did not try again, although I am not sure how you will achieve this in RSpec 3.0.

+1
source

All Articles