Książka jest od dzisiaj obowiązkowa dla kogokolwiek, komu przyjdzie pracować ze mną, aby...zrozumiał moje postępowanie :)
Rozpocząłem rozdziały praktyczne w części Part II. The Process of Test-Driven Development i nie mam wątpliwości, że teoria, a teraz praktyka (wciąż jednak tylko w postaci lektury książki), pozostawią trwały ślad w moim postrzeganiu programowania. Uległem książce całkowicie i czuję się lekko rozdarty.
Z jednej strony książka nawołuje do rozpoczynania projektów od przekrojowych testów integracyjnych, gdzie testuje się wybrane funkcjonalności docelowej aplikacji...bez jej istnienia (chociażby jednej maluczkiej klaski), a z drugiej mam świadomość (albo i nie, ze względu na brak praktycznego doświadczenia), że potrzebna wiedza na początku projektu i do zrobienia tego pierwszego kroku jest niebagatelna, a nerwy trzeba trzymać mocno na postronku. Moje rozpalone są do czerwoności. Chciałoby się trochę poszaleć programistycznie, a tu każą uzbroić się w cierpliwość i zbudować szkielet testujący wybraną funkcjonalność. I nie ma to być trywiał w stylu odczyt z bazki, ale w przypadku aplikacji webowej, najlepiej uruchomić przeglądarkę, wskazać właściwą stronę i sprawdzić wynik! Dla mnie to novum, bo pisanie testów sprowadzałem zwyczajnie do testów jednostkowych, jeśli w ogóle.
W przypadku Grails sprawa się znacznie upraszcza, bo wykonanie dowolnego polecenia budującego typu grails create-controller czy grails create-domain-class tworzy nie tylko wskazany artefakt, ale i...test integracyjny (!) Człowiek, czy chce, czy nie, ugrzązł w TDD na dobre. To, czy wyjdzie to na dobre i czy w ogóle skorzysta się z tego dobrodziejstwa jest tematem na inne przemyślenia, ale fakt faktem Grails zdaje się być pomocnym. Czy aby rzeczywiście można nazywać to "pomocnym"?
I tu pojawiła się moja wątpliwość. Nawet, jeśli Grails faktycznie tworzy testy integracyjne dla wybranego artefaktu czy stworzymy go explicite z grails create-integration-test, to zastanawia mnie, czy to faktycznie odpowiada początkowemu testowaniu integracyjnemu z TDD jak opisano w tej książce. Zdanie z dokumentacji grails create-integration-test:
An integration test differs from a unit test in that the Grails environment is loaded for each test execution.
uspokaja mnie nieznacznie, bo w końcu cała infrastruktura Grails jest uruchamiana w całości przy każdym teście, ale zastanawiam się, czy nie powinienem raczej zbudować war (grails war), uruchomić Tomcata z podłączoną zewnętrzną bazą danych, wdrożyć i uruchomić aplikację i po uruchomieniu przeglądarki uruchomić testy integracyjne (pewnie z pomocą Selenium)?! Znacznie to więcej roboty, ale faktycznie odpowiada bardziej docelowej architekturze, a tak zrozumiałem potrzebę rozpoczęcia prac z testami integracyjnymi, które najbardziej zbliżą nas do docelowego środowiska produkcyjnego. Czy przypadkiem nie poniosło mnie za bardzo? Pomocy!
Jestem już po pierwszym przeczytaniu tej książki (którą powinno się raczej 'studiować' niż tylko raz przeczytać) i tak się zastanawiam, czy w powyższym wpisie nie pomyliłeś koncepcji testu integracyjnego z testem end-to-end?
OdpowiedzUsuńTo dwa rożne rodzaje testów, a wypowiadasz się o testowaniu integracyjnym jakby to był ten rodzaj, który przekrojowo testuje całą aplikację w pełnym środowisku takim jak docelowe (lub maksymalnie zbliżonym do docelowego).
Autorzy dzielą testy na 3 rodzaje, testy jednostkowe - sprawdzają napisane przez nas klasy - głównie logikę biznesową: np. czy podejmowane są odpowiednie decyzje.
Testy integracyjne sprawdzają jak się zachowuje nasza aplikacja na styku z bibliotekami/aplikacjami zewnętrznymi. W tego rodzaju testach często mockuje się nasze klasy biznesowe, ale do akcji wkracza np. baza danych i dostawca JPA razem z np. kontenerem EJB czy servletów.
Dopiero testy end-to-end uruchamiają wszystko razem, bez żadnego ściemniania, mockowania czy podkładania sztucznych obiektów. Wszystko ma być "na żywo".
W wersji grails 1.2.0 przy tworzeniu domeny lub kontrolera nie powstaje test integracyjny a jednostkowy (testy tworzone sa automatycznie w katalogu unit, katalog integration pozostaje pusty).
OdpowiedzUsuńNatomiast budowanie wara, deploy na tomcat i odpalenie testow webowych to podchodzi pod testy funkcjonalne ktore rowniez maja wsparcie w grailsach w postaci Canoo WebTest Plugin. Testy funkcjonalne testuja aplikacje z perspektywy ostatecznego uzytkownika testujac cala aplikacja, jej wszyskie warstwy.
Testy integracyjne natomiast skupiaja sie na testowaniu modulu lub podsystemu calej aplikacji ktory sklada sie z kilku modulow.
Reasumujac moim zdaniem testy funkcjonalne sa testami ktore odpalane byc powinny w srodowisku ktore jest najblizsze srodowisku produkcyjnemy.