如何使用 Capybara 断言元素数量并提供正确的错误消息?

发布于 2024-11-25 07:23:05 字数 466 浏览 1 评论 0原文

我知道在 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

有没有一种方法可以在中编写断言,而不是这种相当晦涩的错误消息这样错误输出将类似于“当匹配'ol li'时,预期:2,发现:1”。显然,我可以自己为这种行为制定一个自定义逻辑 - 我问有没有办法做到“开箱即用”?

就其价值而言,我使用 Selenium 驱动程序和 RSpec。

I know that in Capybara, you can do something like this:

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

However, assuming that page has for instance only one matching element, the error is not very descriptive:

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

Instead of this rather obscure error message, is there a way to write the assertion in such way that error output would be something like 'When matching 'ol li', expected: 2, found: 1'. Obviously I could make a custom logic myself for such a behaviour - I'm asking is there a way to do this 'out of the box'?

For what it's worth, I'm using Selenium driver and RSpec.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

属性 2024-12-02 07:23:05

我更喜欢这个。

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

<一href="https://github.com/jnicklas/capybara/blob/415e2db70d3b19b46a4d3d0fe62f50400f9d2b61/spec/rspec/matchers_spec.rb ">https://github.com/jnicklas/capybara/blob/415e2db70d3b19b46a4d3d0fe62f50400f9d2b61/spec/rspec/matchers_spec.rb

I like this much better.

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

https://github.com/jnicklas/capybara/blob/415e2db70d3b19b46a4d3d0fe62f50400f9d2b61/spec/rspec/matchers_spec.rb

谁把谁当真 2024-12-02 07:23:05

好吧,因为似乎没有开箱即用的支持,我编写了这个自定义匹配器:

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

它现在可以解决问题,我将考虑制作这一部分水豚。

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.

·深蓝 2024-12-02 07:23:05

我认为以下更简单,提供相当清晰的输出,并且不需要自定义匹配器。

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

然后打印出错误:

      expected: 2
       got: 3

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

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)
忘年祭陌 2024-12-02 07:23:05

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

这个怎么样?

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

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
陌伤浅笑 2024-12-02 07:23:05

目前(2013 年 9 月 2 日)Capybara 推荐的最佳实践如下(来源):

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

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

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

烈酒灼喉 2024-12-02 07:23:05

@pandaPower 的答案非常好,但语法对我来说略有不同:

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

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

expect(page).to have_selector('.views-row', :count => 30)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文