Jak potwierdzić liczbę elementów za pomocą Kapibary z odpowiednim komunikatem o błędzie?


86

Wiem, że w Kapibara można zrobić coś takiego:

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

Zakładając jednak, że strona ma na przykład tylko jeden pasujący element, błąd nie jest zbyt opisowy:

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

Czy zamiast tego raczej niejasnego komunikatu o błędzie, istnieje sposób na zapisanie asercji w taki sposób, że wynik błędu będzie podobny do „Podczas dopasowywania„ ol li ”, oczekiwano: 2, znaleziono: 1”. Oczywiście mógłbym sam stworzyć niestandardową logikę dla takiego zachowania - pytam, czy jest sposób na zrobienie tego „po wyjęciu z pudełka”?

Co jest warte, używam sterownika Selenium i RSpec.


Tak dla wszystkich, że "page.should have_css (" ol li ",: count => 2)" został zaimplementowany w kapibarze. Myślę, że jest wysoce użyteczny z zakresami: within ("ol.users-list") do page.should have_css ('li',: count => 3) end
rafaelkin

@rafaelkin, tylko dla wyjaśnienia: czy kapibara zgłasza teraz np. niedopasowanie liczby elementów bardziej szczegółowo? Od jakiegoś czasu nie śledziłem kapibary, ale wtedy, kiedy zadawałem pytanie, chodziło o format komunikatu błędu, a nie taki, page.should have_css("ol li", :count => 2)który nie zostałby już zaimplementowany.
merryprankster

ludzie, mam wrażenie, że obecnie przyjęta odpowiedź (= moja własna) nie jest już najlepsza, ale nie mam czasu (nie pracuję już z Rubim), aby ocenić, które z sugerowanych rozwiązań jest najlepsze. Zmienię zaakceptowaną odpowiedź na tę Richarda tylko dlatego, że zawiera ona wynik asercji, która odnosi się do pierwotnego problemu.
merryprankster

Odpowiedzi:



22

Cóż, wydaje się, że nie ma wsparcia po wyjęciu z pudełka, napisałem ten niestandardowy element dopasowujący:

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

Teraz możesz robić takie rzeczy jak:

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

i uzyskaj wyniki takie jak:

  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

Na razie to działa, przyjrzę się tworzeniu tej części Kapibary.


Wygląda na to, że naprawienie tego w Kapibara nie jest proste: github.com/jnicklas/capybara/issues/331
merryprankster

14

Myślę, że poniższe jest prostsze, daje dość wyraźne wyniki i eliminuje potrzebę dopasowywania niestandardowego.

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

To następnie jest drukowane po błędzie:

      expected: 2
       got: 3

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

9
To nie czeka na spełnienie oczekiwań, np. Gdy wciąż są oczekujące żądania AJAX.
Clemens Helm

9

Edycja: Jak wskazał @ThomasWalpole, użycie allwyłącza oczekiwanie / ponawianie próby Kapibary, więc powyższa odpowiedź @pandaPower jest znacznie lepsza.

Co powiesz na to?

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

2
To całkowicie pokonuje oczekiwanie / ponawianie próby Capybaras i nigdy nie powinno być zalecanym rozwiązaniem.
Thomas Walpole

@ThomasWalpole Nie jestem pewien, o czym mówisz. W jaki sposób szukanie elementu w innym elemencie w jakikolwiek sposób wpływa na oczekiwanie / ponowną próbę w Kapibara?
Constant Meiring

2
@ConstantMeiring To nie jest within, wywołuje .countwyniki, allktóre wyłączają oczekiwanie / ponawianie. Wywołując countwyniki all(dla których pusta "tablica" jest prawidłowym zwrotem) konwertujesz na liczbę całkowitą i porównujesz ją. Jeśli to porównanie zawodzi, oczekiwanie zawodzi. Jeśli zamiast tego przekażesz opcję count do jednego z dopasowań Kapibary, kapibara zaczeka / ponawia próbę znalezienia określonego selektora, aż opcja zliczania zostanie dopasowana (lub wygaśnie Capybara.default_max_wait_time).
Thomas Walpole,

4

Obecna (02.09.2013) najlepsza praktyka zalecana przez Kapibarę jest następująca ( źródło ):

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


-4

Odpowiedź @pandaPower jest bardzo dobra, ale składnia była dla mnie nieco inna:

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

5
Używanie rakiet mieszających nie kwalifikuje się jako „inna składnia”.
premjg

2
Nie jestem programistą Ruby i nie zdawałem sobie sprawy, że te dwie składnie są równoważne. TBH Nie jestem pewien, czy uzasadnia to odrzucenie. To ważna alternatywa. Dla tych, którzy nie wywodzą się z Ruby, może się to wydawać nieoczywiste. To nie było dla mnie.
Nick
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.