4

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

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

谢谢!多里安

PS我正在使用rspec 2.6.0

4

2 回答 2

7

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

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

看起来很恶心。我们的借口是我们上游库中的一个错误,但如果可能的话,我通常会避免这种情况。

于 2012-02-03T00:37:05.013 回答
1

我们使用@Jo 的答案作为访问日志记录异常的一种方式。

在我们将 RSpec 升级到 2.99(以期升级到 3.0)之前,它对我们非常有用。似乎实例变量@exception不再出现在环绕钩子中的示例对象上。

我们必须切换到 before 和 after 钩子,并像以前一样从 after 钩子的示例中访问异常。

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

不过,我们并没有尝试重试,我不确定您将如何在 RSpec 3.0 中实现这一点。

于 2014-06-17T13:03:13.983 回答