如果发生Timeout :: Error,则自动重新运行rspec示例

时间:2011-10-25 10:11:23

标签: rspec rspec2 rspec-rails

首先,我同意在大多数情况下嘲笑外部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

然而,当发生异常时,救援部分永远不会被执行。知道为什么吗?

谢谢! 道连

P.S。我正在使用rspec 2.6.0

2 个答案:

答案 0 :(得分:7)

您无法挽救around块中的异常,因为它们不会传播。但是,如果您绝对必须重新运行失败的示例,则可以从@example中删除当前异常,如下所示:

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

看起来很讨厌。我们的借口是我们上游图书馆的一个错误,但如果可能的话,我通常会避免这种情况。

答案 1 :(得分:1)

我们使用@Jo的答案作为访问记录异常的方法。

在我们将RSpec升级到2.99(以期转向3.0)之前,它对我们很有用。似乎实例变量 @exception 不再出现在around hook中的示例对象上。

我们不得不切换到前后钩子,并像之前钩子的示例一样访问异常。

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

我们并没有尝试重试,我不确定如何在RSpec 3.0中实现这一目标。