適切なエラーメッセージでCapybaraを使用して要素の数をアサートする方法は?


86

カピバラでは、次のようなことができることを知っています。

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

ただし、たとえばページに一致する要素が1つしかない場合、エラーはあまり説明的ではありません。

  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を使用しています。


ご存知のとおり、「page.should have_css( "ol li"、:count => 2)」はカピバラに実装されました。スコープで非常に使いやすいと思います:within( "ol.users-list")do page.should have_css( 'li'、:count => 3)end
rafaelkin 2013

@rafaelkin、明確にするために:capybaraは、たとえば要素数の不一致をより詳細に報告するようになりましたか?私はしばらくカピバラをフォローしていませんが、質問をしたときの問題はエラーメッセージの形式に関するものであり、それpage.should have_css("ol li", :count => 2)はまだ実装されていなかったでしょう。
merryprankster 2013

皆さん、私は現在受け入れられている答え(=私自身)はもはや最良ではないと感じていますが、提案された解決策のどれが最良であるかを評価する時間がありません(Rubyで動作しなくなりました)。元の問題に対処するアサーションの出力が含まれているという理由だけで、受け入れられた回答をリチャードの回答に変更します。
merryprankster 2013年

回答:



22

まあ、すぐにサポートがないように見えるので、私はこのカスタムマッチャーを書きました:

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

それは今のところトリックをします、私はカピバラのこの部分を作ることを調べます。


カピバラでこれを修正するのは簡単ではないようです:github.com/jnicklas/capybara/issues/331
merryprankster 2011

14

以下はより単純で、かなり明確な出力を提供し、カスタムマッチャーの必要性を排除すると思います。

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

これは、エラー時に出力されます。

      expected: 2
       got: 3

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

9
これは、たとえば保留中のajaxリクエストがまだある場合など、期待が実現するのを待ちません。
クレメンスヘルム

9

編集: @ThomasWalpoleが指摘しているように、を使用allするとCapybaraの待機/再試行が無効になるため、@ pandaPowerによる上記の回答の方がはるかに優れています。

これはどう?

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

2
これは、カピバラの待機/再試行を完全に打ち負かし、推奨される解決策になることはありません。
トーマスウォルポール

@ThomasWalpoleあなたが何について話しているのかわかりません。別の要素内で要素を探すことは、カピバラでの待機/再試行にどのように影響しますか?
コンスタントメイリング2017年

2
@ConstantMeiringではなく、その結果をwithin呼び出し.countall待機/再試行を無効にします。(空の「配列」が有効な戻り値である)countの結果を呼び出すことによりall、整数に変換して比較します。その比較が失敗した場合、期待は失敗します。代わりに、カウントオプションをCapybaraのマッチャーの1つに渡すと、capybaraは、カウントオプションが一致するまで(またはCapybara.default_max_wait_timeが期限切れになるまで)、指定されたセレクターの検索を待機/再試行します。
トーマスウォルポール

4

Capybaraが推奨する現在(2013年9月2日)のベストプラクティスは次のとおりです(出典)。

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


-4

@pandaPowerによる答えは非常に良いですが、構文は私にとって少し異なっていました:

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

5
ハッシュロケットの使用は、「異なる構文」とは見なされません。
premjg 2014年

2
私はルビーの開発者ではなく、2つの構文が同等であることに気づいていませんでした。TBHそれが反対票を投じるに値するかどうかはわかりません。これは有効な代替手段です。Rubyのバックグラウンドを持っていない人にとっては、それは明白ではないように思われるかもしれません。それは私のためではありませんでした。
ニック
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.