10

我有一个用于测试 UI 功能的 Cucumber 场景。有时由于几个问题之一,网页需要大量时间来响应,并且 Capybara 超时并出现以下错误。

ruby-1.9.3-p327/lib/ruby/1.9.1/net/protocol.rb:146:in `rescue in rbuf_fill'
ruby-1.9.3-p327/lib/ruby/1.9.1/net/protocol.rb:140:in `rbuf_fill'
ruby-1.9.3-p327/lib/ruby/1.9.1/net/protocol.rb:122:in `readuntil'
ruby-1.9.3-p327/lib/ruby/1.9.1/net/protocol.rb:132:in `readline'
ruby-1.9.3-p327/lib/ruby/1.9.1/net/http.rb:2562:in `read_status_line'
ruby-1.9.3-p327/lib/ruby/1.9.1/net/http.rb:2551:in `read_new' 

我的问题是——

我可以Capybara在超时错误时以某种方式强制 Cucumber 场景或重试(恒定次数)整个场景或步骤吗?

4

2 回答 2

3

也许,你可以这样做:

Around do |scenario, block|
  for i in 1..5
    begin
      block.call
      break
    rescue Timeout::Error
      next
    end
  end
end

但是我不知道这段代码是否因为这个错误而有效(在 Around 钩子中不能多次调用 block

于 2012-12-24T10:38:10.057 回答
1

来自黄瓜书

添加一个eventually method不断尝试运行代码块的代码块,直到它停止引发错误或达到时间限制。

这是该方法的代码:

module AsyncSupport
  def eventually
    timeout = 2
    polling_interval = 0.1
    time_limit = Time.now + timeout
    loop do
      begin 
        yield
      rescue Exception => error
      end
      return if error.nil?
      raise error if Time.now >= time_limit sleep polling_interval
    end
  end
end
World(AsyncSupport) 

从 step_definition 调用的方法如下:

Then /^the balance of my account should be (#{CAPTURE_CASH_AMOUNT})$/ do |amount|
  eventually { my_account.balance.should eq(amount) }
end
于 2012-12-24T11:15:33.637 回答