【问题标题】:Rerun Cucumber step only in case of specific failure仅在特定失败的情况下重新运行 Cucumber 步骤
【发布时间】:2017-01-31 06:02:20
【问题描述】:
使用 Selenium 在 CircleCI 中运行 Cucumber 有时会由于 CircleCI 的性能而导致测试失败。一个常见的故障是Net::ReadTimeout 错误,这似乎永远不会在本地发生。我想从该错误中挽救步骤并重试,但我确实不想重新运行所有失败的测试。
我可以将构建救援放入似乎触发此错误的特定步骤中,但理想情况下,我将能够为 Cucumber 提供一次或两次救援的错误列表,以重新运行该步骤,然后最终让错误通过。
类似:
# support/env.rb
Cucumber.retry_errors = {
# error => number of retries
"Net::ReadTimeoutError" => 2
}
这样的东西存在吗?
【问题讨论】:
标签:
ruby-on-rails
ruby
selenium
cucumber
【解决方案1】:
如果你在 Cucumber 中找到了你想要的东西,我会很惊讶。
重新运行一个失败的步骤只是为了确保它是一个实际的失败,而不仅仅是一个随机的网络故障,从我的角度来看,解决了错误的问题。
我的方法是查看您正在寻找的验证是否可以在没有网络的情况下进行。如果我真的必须重新运行几次以确保错误确实是错误,我可能还会考虑使用除 Cucumber 之外的其他工具。然而,这会让我陷入另一个兔子洞。你应该跑多少次,门槛是多少?是否应该五分之三的执行通过才能宣布通过测试?在我眼里它变得非常难看。
【解决方案2】:
看起来这个问题是 Selenium 在第一次测试中编译资产需要很长时间。后续测试使用已编译的资产并且没有问题。查看this Github issue 后,我提高了 Selenium 的超时限制。
Capybara.register_driver :chrome do |app|
http_client = Selenium::WebDriver::Remote::Http::Default.new
http_client.timeout = 120 # default is 60 seconds
Capybara::Selenium::Driver.new(app, browser: :chrome, http_client: http_client)
end
【解决方案3】:
我知道这并没有专门捕获特定类的重试,但现在确实有一种干净的方法可以在 cucumber 中执行此操作,特别是因为在搜索“rerun cucumber”时这个结果出现在 Google 中
在您的 cucumber.yml 文件中,您现在可以执行以下操作:
<%
std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} --strict --tags 'not @wip'"
std_opts_with_retry = "#{std_opts} --no-strict-flaky --retry 3"
%>
default: <%= std_opts_with_retry %> features
关于“片状”测试是否应被视为失败存在很大的哲学争论。同意如果“--strict”通过,默认应该是“片状”测试(又名:第一次运行失败并通过下一次运行的测试)使运行失败。因此,为了使不稳定的测试不会“失败”您的测试运行,您可以传递额外的 --no-strict-flaky 以及 --retry 3 选项,现在任何有时可能在您的 CI 平台上花费可变时间的测试都不会t 需要重建整个提交。
执行此操作时需要注意的一点:一般来说,我建议您将超时时间降低到一个合理的限制,大多数测试都可以通过而无需长时间等待,尽管我理解在这种情况下它可以容纳更长的时间编译时间。