Làm thế nào để xác nhận số phần tử bằng cách sử dụng Capybara với thông báo lỗi thích hợp?


86

Tôi biết rằng ở Capybara, bạn có thể làm điều gì đó như sau:

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

Tuy nhiên, giả sử trang đó chỉ có một phần tử phù hợp, ví dụ, lỗi không mang tính mô tả:

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

Thay vì thông báo lỗi khá khó hiểu này, có cách nào để viết xác nhận theo cách mà đầu ra lỗi sẽ giống như 'Khi khớp' ol li ', mong đợi: 2, tìm thấy: 1'. Rõ ràng là tôi có thể tự mình đưa ra một logic tùy chỉnh cho một hành vi như vậy - tôi đang hỏi có cách nào để thực hiện điều này 'ra khỏi hộp' không?

Đối với những gì nó đáng giá, tôi đang sử dụng trình điều khiển Selenium và RSpec.


Chỉ để mọi người biết, "page.should have_css (" ol li ",: count => 2)" đã được triển khai trong capybara. Tôi nghĩ rằng nó là rất cao có thể sử dụng với phạm vi: trong vòng ( "ol.users-list") làm have_css page.should ( 'li',: count => 3) end
rafaelkin

@rafaelkin, chỉ cần làm rõ: capybara hiện có báo cáo ví dụ: sự không khớp về số lượng phần tử với chi tiết hơn không? Tôi đã không theo dõi capybara trong một thời gian, nhưng vấn đề hồi đó khi tôi đặt câu hỏi là về định dạng của thông báo lỗi, không phải điều đó page.should have_css("ol li", :count => 2)sẽ chưa được triển khai.
merryprankster

mọi người, tôi có cảm giác rằng câu trả lời được chấp nhận hiện tại (= của riêng tôi) không còn là tốt nhất, nhưng không có thời gian (không còn làm việc với Ruby) để đánh giá giải pháp được đề xuất nào là tốt nhất. Tôi sẽ thay đổi câu trả lời được chấp nhận thành câu trả lời của Richard chỉ vì nó bao gồm đầu ra của khẳng định giải quyết vấn đề ban đầu.
merryprankster

Câu trả lời:



22

Vâng, có vẻ như không có hỗ trợ ngoài hộp, tôi đã viết trình so khớp tùy chỉnh này:

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

Bây giờ, bạn có thể làm những việc như:

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

và nhận đầu ra như:

  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

Bây giờ nó là một mẹo nhỏ, tôi sẽ xem xét việc làm phần này của Capybara.


Trông giống như sửa chữa này trong Capybara là không đơn giản: github.com/jnicklas/capybara/issues/331
merryprankster

14

Tôi nghĩ cách sau đây đơn giản hơn, cho đầu ra khá rõ ràng và loại bỏ sự cần thiết phải có trình so khớp tùy chỉnh.

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

Điều này sau đó in ra do lỗi:

      expected: 2
       got: 3

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

9
Điều này không chờ đợi kỳ vọng trở thành hiện thực, ví dụ như khi vẫn có các yêu cầu ajax đang chờ xử lý.
Clemens Helm

9

Chỉnh sửa: Như đã chỉ ra bởi @ThomasWalpole, việc sử dụng alltắt tính năng chờ / thử lại của Capybara, vì vậy câu trả lời ở trên của @pandaPower tốt hơn nhiều.

Còn cái này thì sao?

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

2
Điều này hoàn toàn đánh bại việc chờ / thử lại Capybaras và không bao giờ nên là một giải pháp được khuyến nghị.
Thomas Walpole

@ThomasWalpole Tôi không chắc bạn đang nói về điều gì. Làm thế nào để tìm kiếm một phần tử trong một phần tử khác theo bất kỳ cách nào lại chạm vào việc chờ đợi / thử lại trong Capybara?
Constant Meiring

2
@ConstantMeiring Nó không phải vậy within, nó đang gọi .countkết quả của allđiều đó vô hiệu hóa tính năng chờ / thử lại. Bằng cách gọi countkết quả của all(mà một "mảng" trống là giá trị trả về hợp lệ), bạn chuyển đổi thành một số nguyên và so sánh nó. Nếu sự so sánh đó không thành công thì kỳ vọng không thành công. Thay vào đó, nếu bạn chuyển tùy chọn đếm cho một trong các trình so khớp của Capybara, capybara sẽ đợi / thử lại việc tìm bộ chọn được chỉ định cho đến khi tùy chọn đếm khớp (hoặc Capybara.default_max_wait_time hết hạn).
Thomas Walpole

4

Phương pháp hay nhất hiện tại (9/2/2013) do Capybara đề xuất là ( nguồn ) sau:

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


-4

Câu trả lời của @pandaPower rất hay, nhưng với tôi thì cú pháp hơi khác:

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

5
Sử dụng tên lửa băm không đủ tiêu chuẩn là "cú pháp khác".
Premjg

2
Tôi không phải là một nhà phát triển ruby ​​và không nhận ra rằng hai cú pháp là tương đương nhau. TBH Tôi không chắc nó có đảm bảo sự ủng hộ không. Đó là một sự thay thế hợp lệ. Đối với những người không có nền tảng về Ruby, nó có vẻ không rõ ràng. Nó không dành cho tôi.
Nick
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.