Refaktoryzacja 'I should see "...."' w cucumberze

W cucumberze często pisze się scenariusze tego typu:

Given I have no articles When I add new article titled "First!" Then I should be on articles list And I should see "First!"
Fajny i prosty scenariusz, ale może prowadzić do błędów. Na przykład: klient prosi, żeby dodać po prawej w sidebarze najpopularniejsze artykuły. Jako, że w czasie wykonywania takiego scenariusza w bazie jest tylko jeden artykuł, to będzie on widniał zarówno na liście artykułów jak i najpopularniejszych artykułów. Dlatego jeżeli podczas jakiejś refaktoryzacji przez pomyłkę coś się stanie z listą artykułów, to test może dalej przechodzić, a tak naprawdę nie powinien.

Na WRUGU powiedziałem, że używam do tego Nokogiri, ale szukam lepszego rozwiązania. W domu przejrzałem kod i stwierdziłem, że jest to tak naprawdę całkiem niezłe rozwiązanie :slight_smile:

Przypuśćmy, że testujemy wyszukiwarkę:

And I should see "First article." in the search results

Jest to wbrew pozorom banalne do zaimplementowania:

[code]# helper, który będzie zwracał Document nokogiri
def nokogiri_doc

wkładamy w nokogiri HTML, przykłąd dla celerity

Nokogiri::HTML($browser.document.asXml)
end

teraz sam krok

Then /^I should see “([^”]*)" in the search results$/ do |text|
content = nokogiri_doc.css("#search_results").to_s
content.should contain(text)
end[/code]
Jak widać można to całkiem prosto zaimplementować. Można by nawet pójść krok dalej i napisać coś w stylu

I should see "some text" in "#search_results"

Z tym, że szczerze mówiąc ja bym nie tego nie polecał, bo pisząc bardziej generalny krok ułatwiamy sobie pracę, ale żadna nietechniczna osoba nie będzie wiedziała dlaczego niby tam jest jakiś # i po co to podkreślenie.

Można zawsze uprościć jeszcze helpery:

[code]def element_content(css)
content = nokogiri_doc.css("#search_results").to_s
end

Then /^I should see “([^”]*)" in the search results$/ do |text|
element_content("#search_result").should contain(text)
end[/code]
W tym wypadku do wszystkiego wystarczy jednolinijkowy krok, więc pisania jest niedużo a zysk chyba całkiem niezły :slight_smile:

Zna ktoś jakieś lepsze rozwiązanie?

Ja korzystam z wbudowanych (chyba?) w tandem Cucumber+Webrat helperow typu:

When /^I press "([^\"]*)" within "([^\"]*)"$/ do |button, selector| within selector do |scope| scope.click_button(button) end end
Po lekkich modyfikacjach można otrzymać helpery w stylu:

[code=“Ruby”]Then /^I should see “([^”]*)" in the navbar$/ do |text|
within “.navbarpath” do
response.should contain(text)
end
end

Then /^I should see “([^”])" within “([^”])"$/ do |text, selector|
within selector do |selector|
selector.should contain(text)
end
end

Then /^I should not see “([^”])" within “([^”])"$/ do |text, selector|
within selector do |selector|
selector.should_not contain(text)
end
end[/code]

Sweet! :smiley:

Nie wiedziałem o takim czymś. Pomyślę o przeportowaniu do celerity.

Poczytanie o API Webrata w RSpec Book było najbardziej oświecającym doświadczeniem ostatniego tygodnia – generalnie Webrat potrafi wyciągać elementy według selektorów CSS, warto się z tym zapoznać :wink:

Chyba się wykosztuję wreszcie na RSpec book jak tak zachwalasz :smiley: