Moje „ah-ha!” chwile na temat testowania w Ruby i Railsach nadeszły, kiedy naprawdę usiadłem i przeczytałem ostateczne zasoby na ten temat, książki Rspec i Cucumber . Podzielam twoją początkową pogardę dla Ogórka, ale potem zdałem sobie sprawę, że patrzę na zdjęcie z całkiem niewłaściwego punktu widzenia.
Zasadniczo w Cucumber chodzi o BDD (programowanie oparte na zachowaniu) - używasz Cucumber do planowania swoich funkcji, nad czym będziesz dalej pracować. Hmm, następnie chcesz, aby użytkownicy mogli promować posty na forum lub coś takiego (aby ukraść przykład;)) Więc piszesz coś prostego.
Given I am logged in
And I can see the post "BDD is awesome"
When I vote the post up
Then the post should have one more vote
And the page should show a message thanking me for my vote.
Zauważ, że nie ma tam żadnych odniesień do żadnego powiązanego kodu. To przychodzi w twoich krokach. Podczas refaktoryzacji kodu może być konieczna zmiana definicji kroków, ale zachowanie (funkcja) nigdy nie będzie musiało się zmieniać.
Teraz za każdym razem, gdy uruchamiasz funkcję Ogórek, zostaniesz prawie poprowadzony przez proces testowania tej funkcji za pomocą TDD (programowanie testowe). Odbywa się to na niższym poziomie za pomocą RSpec.
Pierwsze uruchomienie - moja definicja pierwszego kroku jest niezdefiniowana. Skopiuj blok, aby go zdefiniować, powiedzmy user_steps.rb, a nawet session_steps.rb, ponieważ dotyczy on użytkowników i ich sesji. Jak zdefiniujesz, że użytkownik jest zalogowany? Możesz przeprowadzić je przez proces logowania.
Given /^I am logged in$/ do
visit login_path
fill_in :name, :with => 'Joe'
fill_in :password, :with => 'Password'
click_button 'submit'
end
Powinien być szczęśliwy. Drugi krok.
Given /^I can see the post "(.+)"$/ do |name|
visit post_path(Post.find_by_name(name))
end
Znowu dość łatwe. Pamiętaj, że jeśli całkowicie przerobimy proces logowania lub sposób, w jaki nasze posty są definiowane i wyświetlane, nie musimy zmieniać tego zachowania. Trzeci krok.
When /^I vote the post up$/ do
pending
end
Tutaj zaczynasz mówić o nowej funkcjonalności, ale nie wiesz jeszcze, jak to będzie działać. Jak głosujesz na post? Możesz kliknąć obraz +1 lub coś, co wysyła wiadomość ajax do kontrolera, który zwraca JSON, lub coś takiego. Teraz możesz przejść do czystych testów Rspec.
- Przetestuj swój widok, aby upewnić się, że wyświetlany jest obraz +1,
- Przetestuj swój kontroler, czy zachowuje się poprawnie, gdy otrzyma dane zapytanie we właściwym formacie (zarówno szczęśliwe, jak i nieszczęśliwe ścieżki - co jeśli otrzymany zostanie niepoprawny identyfikator posta? Co się stanie, jeśli użytkownik wykorzysta swoje 25 ocen pozytywnych w ciągu jednego dnia? Czy prawidłowo zwiększa liczbę głosów?)
- Przetestuj skrypt JavaScript, aby poprawnie reagował, gdy dostanie kroplę JSON w odpowiednim formacie (czy aktualizuje obraz +1, aby pokazać, że został użyty? (Myśląc o Google+ tutaj ...) Czy wyświetla wiadomość z podziękowaniem? Itp. )
Wszystko to nie wpływa na zachowanie - ale kiedy skończysz testowanie na niższym poziomie, wypełnienie definicji kroku głosowania posta będzie banalne. To może być tak proste jak click_link '+1'
. Pozostałe etapy to testowanie wyników, które znowu powinny być łatwe do zrobienia. A kiedy skończysz, wiesz, że Twoja funkcja jest kompletna i gotowa. Jeśli konieczne zachowanie się zmieni, możesz ulepszyć swoją funkcję, w przeciwnym razie możesz poprawić kod implementacyjny w sposób całkowicie bezpieczny.
Mam nadzieję, że to ma sens. Wszystko to nie mieści się w mojej głowie, ale myślę, że pokazuje różnicę między BDD i TDD oraz dlaczego Cucumber i RSpec służą różnym potrzebom.