如何使用适当的错误消息断言水豚元素的数量?

我知道在水豚,你可以这样做:

page.should have_css("ol li", :count => 2)

但是,假设该页面只有一个匹配元素,那么错误描述性就不是很强:

  1) initial page load shows greetings
Failure/Error: page.should have_css("ol li", :count => 2)
expected css "ol li" to return something

除了这个相当模糊的错误消息之外,是否有一种方法可以编写这样的断言,即错误输出类似于“当匹配‘ ol li’时,预期: 2,found: 1”。显然,我可以自己为这种行为制定一个自定义逻辑——我是在问,有没有一种方法可以做到这一点“不按常理出牌”?

不管怎样,我使用的是 Selenium 驱动程序和 RSpec。

47149 次浏览

Well, as it seems there is no support out-of-the-box, I wrote this custom matcher:

RSpec::Matchers.define :match_exactly do |expected_match_count, selector|
match do |context|
matching = context.all(selector)
@matched = matching.size
@matched == expected_match_count
end


failure_message_for_should do
"expected '#{selector}' to match exactly #{expected_match_count} elements, but matched #{@matched}"
end


failure_message_for_should_not do
"expected '#{selector}' to NOT match exactly #{expected_match_count} elements, but it did"
end
end

Now, you can do stuff like:

describe "initial page load", :type => :request do
it "has 12 inputs" do
visit "/"
page.should match_exactly(12, "input")
end
end

and get output like:

  1) initial page load has 12 inputs
Failure/Error: page.should match_exactly(12, "input")
expected 'input' to match exactly 12 elements, but matched 13

It does the trick for now, I will look into making this part of Capybara.

I think the following is simpler, gives fairly clear output and eliminates the need for a custom matcher.

page.all("ol li").count.should eql(2)

This then prints out on error:

      expected: 2
got: 3


(compared using eql?)
(RSpec::Expectations::ExpectationNotMetError)

The current (9/2/2013) best practice recommended by Capybara is the following (source):

page.assert_selector('p#foo', :count => 4)

The answer by @pandaPower is very good, but the syntax was slightly different for me:

expect(page).to have_selector('.views-row', :count => 30)

Edit: As pointed out by @ThomasWalpole, using all disables Capybara's waiting/retrying, so the answer above by @pandaPower is much better.

How about this?

  within('ol') do
expect( all('.opportunity_title_wrap').count ).to eq(2)
end