Rspec 如何使用带有正确错误消息的Capybara断言元素数?

Rspec 如何使用带有正确错误消息的Capybara断言元素数?,rspec,dsl,capybara,Rspec,Dsl,Capybara,我知道在水豚,你可以做这样的事情: 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 有没有一种方法可以代替这个

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

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,发现为:1”。显然,我可以自己为这种行为制定一个自定义逻辑——我在问,有没有一种“开箱即用”的方法


值得一提的是,我使用的是Selenium驱动程序和RSpec。

由于似乎没有现成的支持,我编写了以下自定义匹配程序:

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
现在,您可以执行以下操作:

describe "initial page load", :type => :request do
    it "has 12 inputs" do
        visit "/"
        page.should match_exactly(12, "input")
    end
end
并获得如下输出:

  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

现在它已经成功了,我将研究制作水豚的这一部分。

我更喜欢这一部分

expect(page).to have_selector('input', count: 12)

我认为以下方法更简单,输出相当清晰,无需定制匹配器

page.all("ol li").count.should eql(2)
然后在出现错误时打印:

      expected: 2
       got: 3

  (compared using eql?)
  (RSpec::Expectations::ExpectationNotMetError)
水豚目前(2013年9月2日)推荐的最佳实践如下():


page.assert\u选择器('p#foo',:count=>4)
由@pandaPower给出的答案非常好,但语法对我来说略有不同:

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

编辑:正如@ThomasWalpole所指出的,使用
all
会禁用水豚的等待/重试,因此@pandaPower给出的上述答案要好得多

expect(page).to have_selector('input', count: 12)
这个怎么样

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

看来在Capybara中解决这个问题并不简单:大家都知道,在Capybara中实现了“page.should have_css(“ol li”,:count=>2)”。我认为它在作用域中非常有用:在(“ol.users列表”)中,do page.should有_css('li',:count=>3)end@rafaelkin,只是澄清一下:水豚现在是否报告了更详细的元素计数不匹配?我已经有一段时间没有关注过水豚了,但是当我提出这个问题时,当时的问题是关于错误消息的格式,而不是
page.should_css(“ol li”,count=>2)
不会已经实现。伙计们,我感觉目前接受的答案(=我自己的)不再是最好的,但没有时间(不再使用Ruby)评估建议的解决方案中哪一个是最好的。我将把公认的答案改为Richard的答案,因为它包含了解决原始问题的断言输出。这并不需要等待期望实现,例如,当仍然存在未决的ajax请求时。使用哈希火箭不符合要求“不同的语法。”我不是ruby开发者,也不知道这两种语法是等价的。TBH我不确定这是否值得否决。这是一个有效的选择。对于那些不是ruby背景的人来说,这似乎不明显。这不适合我。也适用于
have_css
expect(page)。have_css('input',count:12)
这完全击败了水豚的等待/重试,不应该是一个推荐的解决方案。@ThomasWalpole我不知道你在说什么。在另一个元素中寻找一个元素如何影响到水豚的等待/重试?@ConstantMeiring它不是中的
,它在调用
。count
禁用等待/重试的
all
的结果。通过对
all
的结果调用
count
(空的“数组”是有效的返回)将转换为整数并对其进行比较。如果比较失败,则期望值将失败。如果将count选项传递给Capybara的某个匹配器,则Capybara将等待/重试查找指定的选择器,直到count选项匹配为止(或Capybara.default_max_wait_time过期)。