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.
Moim zdaniem testowanie jest sztuką. Robiąc TDD (używając RSpec lub innego frameworka) początkowo wydaje się, że „marnujesz swój czas”. Jest to zrozumiałe, ponieważ nie piszesz żadnego kodu produkcyjnego.
Jednak zaczynasz dostrzegać korzyści z TDD, gdy musisz ulepszyć bazę kodu, jednocześnie upewniając się, że wszystko inne nadal działa. TDD pomaga wychwycić błędy regresji jak najwcześniej. Dzięki temu zaoszczędziłem wiele dni pracy, ponieważ skoncentrowałem się na testach, które wykazały moje błędy.
Ponadto posiadanie testów może być korzystne dla recenzji kodu, ponieważ recenzent może zobaczyć, jakie scenariusze testujesz i jak ma być używany kod.
Gdy zaczniesz się huśtać w TDD, robienie czegokolwiek innego będzie złe.
źródło
Uważam, że masz rację na froncie Ogórka. Pisanie tych wszystkich kroków jest dużym problemem, a korzyści nie uzasadniają bólu. Napisałem obszernie o sześciu wadach używania Ogórka tutaj: Po co zawracać sobie głowę testowaniem ogórka?
Testy jednostkowe i regularne testy integracyjne, wykonywane za pomocą Rspec lub Test :: Unit, mają wiele sensu, ale na szczęście są one znacznie szybsze niż testy ogórkowe. Na przykład możesz użyć czystego Ruby zamiast walczyć z nieprzyzwoitą i niezręczną składnią Korniszona.
źródło
Osobiście w to wierzę
RSpec testing is a definite must
. Powiedzmy na przykład, że chcesz napisać nową funkcję, która ma również odniesienie do innej funkcji, a do tej funkcji można odwoływać się za pomocą innych modułów lub metod. Jak więc upewnić się, że to, co piszesz, nie psuje żadnej innej części aplikacji?Załóżmy, że masz dużą aplikację i że zakodowałeś coś trywialnego w porównaniu z ogólną aplikacją. Czy przetestujesz ponownie całą aplikację, klikając każdy link w aplikacji, aby upewnić się, że działa za każdym razem, gdy zmieniasz pojedynczy wiersz kodu?
Uważam jednak, że testowanie ogórka nie jest koniecznością. Myślę, że testowanie integracji przy użyciu samego RSpec ma większy sens, dopóki klient nie sprawdzi testów. Co z mojego doświadczenia jest rzadkie. Jeśli twój zespół składa się wyłącznie z programistów, myślę, że powinieneś raczej zastąpić kroki Ogórka do testowania funkcji RSpec. I myślę, że po RSpec 3 DSL testy są dość czytelne.
Np .:
Definicja kroku ogórka:
Test funkcji RSpec:
Myślę, że zamiast funkcji Cucumber, funkcje RSpec robią to samo bez dodatkowego bólu głowy związanego z pisaniem kolejnych definicji kroków.
Poza tym jest to wyłącznie twoja własna preferencja.
Mam nadzieję, że to pomoże ci trochę zrozumieć.
źródło
Moim zdaniem najpierw należy rozróżnić praktyki i konkretne ramy. Ogórek to nie BDD, RSpec to nie TDD.
Jeśli chcesz przetestować system RSpec jako dobre narzędzie, możesz wykonać TDD lub BDD za pomocą RSpec, w rzeczywistości TDD i BDD są tym samym. Ktoś mówi: „BDD to TDD zrobione poprawnie” i całkowicie się z tym zgadzam, BDD przede wszystkim chodzi o testowanie cech / zachowań zamiast testowania metod / klas. W rzeczywistości TDD, którą opisuje Kent Beck o swoich funkcjach, ale BDD pomaga wielu ludziom zrozumieć tę kluczową różnicę i jej wielki wkład od Dana Northa dla społeczności programistów.
Użyj Ogórka, jeśli uważasz, że potrzebujesz lepszego narzędzia do komunikowania się z ludźmi biznesu, na przykład, jeśli ogórek pozwala, aby ludzie biznesu lub właściciel produktu pomagali zespołowi w pisaniu lub korygowaniu scenariuszy. Inni ludzie lubią ogórki, ponieważ te scenariusze są naprawdę dobrą dokumentacją systemu na żywo, jeśli uważasz, że potrzebujesz tego typu dokumentacji, spróbuj ogórka.
W podsumowaniu:
Oczywiście dwa ostatnie wiążą się z wysokimi kosztami, musisz ocenić, czy naprawdę tego potrzebujesz, i warte wysiłku, to oczywiście zależy całkowicie od twojego projektu i twojego środowiska oraz od decyzji.
Ale zawsze pamiętaj, że RSpec i Cucumber to tylko narzędzia, a narzędzia rozwiązują konkretne problemy, jaki problem chcesz rozwiązać ?, zadaj sobie to pytanie i prawdopodobnie jesteś w lepszej pozycji, aby wybrać odpowiednie narzędzie. Lepszym programistą jest podejmowanie tych decyzji, a nie korzystanie z frameworka / narzędzia / biblioteki / technologii X lub Y.
źródło