rspec它阻止内部循环

时间:2018-02-04 20:39:32

标签: ruby rspec

我想测试页面上的每个链接都返回一个特定的状态代码。我有一个工作测试,像这样:

it "does not throw 400/500 error for any link" do
  visit '/'
  within(".wrapper") do
    all('a').each do |link|
      http_status = Faraday.head(link[:href].to_s).status
      puts "#{link.text}, #{http_status}"
      expect((400..500)).not_to include(http_status) 
    end
  end

然而,这对于输出来说非常糟糕,因为在一次测试中检查了所有链接(因此测试中的放置以显示哪个链接破坏了测试)。我希望能够对每个链接进行单独的测试,而无需为页面上的每个链接手动编写测试。

我试过了:

context "does not throw 400/500 error for any link" do
  visit '/'
  within(".wrapper") do
    all('a').each do |link|
      it "does not throw 400/500 error for #{link}" do
        link_status_code_is_not(link, (400..500))
      end
    end
  end
end

并收到此错误

`visit` is not available on an example group (e.g. a `describe` or
`context` block). It is only available from within individual examples 
(e.g. `it` blocks) or from constructs that run in the scope of an 
example (e.g. `before`, `let`, etc).

所以我尝试将访问移动到之前的挂钩但是在内部块中遇到了同样的问题(我无法真正移动)。我已经能够在茉莉花中做这样的事了,但我似乎找不到在rspec中做到这一点的方法。

TL:博士;有没有办法在rspec中将它块放在循环中?

1 个答案:

答案 0 :(得分:2)

您可以在循环内创建it块:

RSpec.describe "numbers" do
  [*1..10].each do |number|
    it "#{number} should not be multiple of 10" do
      expect(number % 10).not_to be_zero
    end
  end
end

你的问题是,它看起来不像visit块之外的it(或“在示例范围内运行的构造”),你需要获取数据从您visit的页面中循环并从该数据创建it块。我不确定这是否可以很好地完成。

如果你想要的只是链接的更好输出,你可以使用aggregate_failuresCustomized messages来为你的测试提供更好的输出。对于一个人为的例子,假设我有大量的动态,只能在it块内或在示例范围内运行的构造,数字对,我需要确保它们的产品都不是倍数10:

RSpec.describe "numbers" do
  it "are not a multiple of 10" do
    [*1..10].product([*1..10]).each do |base, multiplier|
      expect((base * multiplier) % 10).not_to be_zero
    end
  end
end

这里的输出不是很好,它只是告诉我期望0.zero?返回false,得到真实,而不是哪一对数字失败。通过使用聚合失败和自定义消息,我可以解决这个问题:

RSpec.describe "numbers" do
  it "are not a multiple of 10" do
    aggregate_failures do
      [*1..10].product([*1..10]).each do |base, multiplier|
        expect((base * multiplier) % 10).not_to be_zero, "#{base} * #{multiplier} is a multiple of 10"
      end
    end
  end
end

现在,我在统计数据中只报告了1次失败(这可能对您的用例有好处或坏处),但我得到27次失败:

Failures:

  1) numbers are not a multiple of 10
     Got 27 failures from failure aggregation block.

     1.1) Failure/Error: ...
            1 * 10 is a multiple of 10
          # ...backtrace...
     1.2) Failure/Error: ...
            2 * 5 is a multiple of 10
          # ...backtrace...
     ...
     1.27) Failure/Error: ...
             10 * 10 is a multiple of 10