07 marca 2010

Grails a TDD z perspektywy "Growing Object-Oriented Software, Guided by Tests"

Growing Object-Oriented Software, Guided by TestsKsiąż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!