我想测试页面上的每个链接是否返回特定的状态代码。我有一个工作测试,是这样的:
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
Run Code Online (Sandbox Code Playgroud)
然而,这对于输出来说非常糟糕,因为所有链接都在一个测试中检查(因此测试中的 puts 向我显示哪个链接破坏了测试)。我希望能够对每个链接进行单独的测试,而无需为页面上的每个链接手动编写测试。
我试过这个:
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
Run Code Online (Sandbox Code Playgroud)
并得到这个错误
`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).
Run Code Online (Sandbox Code Playgroud)
所以我尝试将访问移动到一个 before 钩子,但遇到了与内块相同的问题(我无法真正移动)。我已经能够在 jasmine 中做这样的事情,但我似乎找不到在 rspec 中做到这一点的方法。
tl:博士;有没有办法将 it 块放在 rspec 的循环中?
您可以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
Run Code Online (Sandbox Code Playgroud)
您的问题是它看起来不像您可以visit在it块之外(或“在示例范围内运行的构造”),并且您需要从页面中获取数据visit并循环遍历并it从中创建块数据。我不确定这是否可以很好地完成。
如果您想要的只是更好的链接输出,您可以aggregate_failures与自定义消息一起使用,为您的测试提供更好的输出。对于人为的示例,假设我有大量动态,仅在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
Run Code Online (Sandbox Code Playgroud)
这里的输出不是很好,它只是告诉我期望0.zero?返回 false,得到 true,而不是哪对数字失败。不过,通过使用聚合失败和自定义消息,我可以解决这个问题:
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
Run Code Online (Sandbox Code Playgroud)
现在,我在统计信息中只报告了 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
Run Code Online (Sandbox Code Playgroud)