Posts Tagged ‘TDD’

Trzeźwe spojrzenie na: Design By Contract by Google

Author: Konrad Malawski (Konrad Malawski) | luty 9th, 2011
avatar

Design By Contract

Dzisiejszy wpis będzie o znanej i generalnie dość znanej i mającej wiele zalet metodyce Design By Contract. Temat „wypłynął” ponownie dla wielu javovców tym razem dzięki wydaniu biblioteki  CoFoJa (o którym właśnie będzie ten post) przez dwóch pracowników Google przy ścisłej współpracy z autorem pierwowzoru tego projektu. Dlaczego jednak nietypowy tytuł posta – „trzeźwe spojrzenie”? Ponieważ w odróżnieniu od niektórych nie oceniam technologii na podstawie „wow factor” a realnej używalności. Gotowi mini review tego toola? No to lecimy… :-)

Contracts For Java

Na początek warto rzucić okiem na googlowy blog gdzie ogłoszono premierę tego narzędzia oraz oczywiście samą stronę domową projektu CoFoJa. Oczywiście na samym przekierowaniu nie poprzestanę więc zaczniemy od mini definicji od strony użytkownika metodyki design by contract. Jak możemy przeczytać chociażby w pragmatycznym programiście metodyka ta ma dość spory potencjał i ciekawe możliwości – generalnie chodzi o określanie „kontraktów” na naszych metodach. Zakładanie kontraktów ma pewną wyższość nad pisanie testów jednostkowych ponieważ możemy kontrakt założyć na interfejsie a wszystkie implementujące go klasy będą z nim związane

Kontrakt może na przykład zapewnić:

  • wykonanie danej metody tylko i wyłącznie wtedy gdy przekazane jej argumenty spełniają pewne kryteria (w kontekście CoFoJa byłoby to @Requires)
  • zagwarantowanie spełnienia pewnych warunków po opuszczeniu metody (w kontekście CoFoJa byłoby to @Ensures ewentualnie @ThrowEnsures jeśli chcemy mieć kontrakt na rzucenie wyjątku)
  • zagwarantowanie ogólnych warunków na konkretnej np. klasie (@Invariant)

Ok, skoro znamy podstawowe building blocks (zaczerpnięte skądżeby inąd niż z Eiffla oczywiście) zobaczmy jakieś przykładowe poadnotowane nimi API:

A teraz praktycznie

Najlepiej jest chwilkę się w niego wgryźć, powinien być stosunkowo zrozumiały. Nie chcemy nigdy mieć ujemnej ilości bananów – spowodowałoby to złamanie kontraktu. Podobne przykładowe kontrakty wejściowe/wyjściowe widzimy na metodach oraz jeden mały tip: metoda old() jest dostarczana automagicznie i oznacza „starą wartość tego wywołania” czyli przed wykonaniem metody na którą zakładamy ten kontrakt. Poza tym mamy tutaj do czynienia w sumie z zwyczajnym kodem Java który niestety jest wewnątrz stringa… Świadomy programista zapewne już ma zapaloną lampkę alarmową, że to będzie nie refaktorowalne i bez sensu… Na pocieszenie dodam iż kod Java zawarty w tych stringach faktycznie jest „kompilowany”i jak coś popsujemy składniowo, kontrakty się nie skompilują i dostaniemy normalne informacje jakby to się nam nie kompilował normalny „nasz kod”. Co do wygody refaktoringu… Na szczęscie korzystam z porządnego IDE (IntelliJ IDEA) i takie „problemy” mnie nie dotyczą ;-). Wybrałem inject języka Groovy do tych stringów aby parser składniowy nie dziwił się pojawienia się metody old() „z nikąd”: Problem z „nie podpowiadaniem metod” jak i „nie da się refaktorować” jak widać został od razu wyeliminowany :-) Hooray for JetBrains. Poszukajmy jednak kolejnego problemu z tym API… Tak jest, @ThrowEnsures jest trochę brzydki a nie koniecznie musi być cały w stringu. Jak działa obecnie? Przekazujemy mu listę stringów gdzie parami występują „wyjątek” + „warunek kiedy ma zostać rzucony”. Chętniej zobaczył bym to w formie podobnej do poniższej (tylko szybki szkic taki), a wy?

Ok czas na uruchomienie kodu z „włączonymi kontraktami”… I… niestety nie okazało się to takie trywialne na obecnym etapie projektu. Niestety trzeba sobie ręcznie poustawiać processowanie adnotacji (norma, tutaj się niewiele zmieni) jednak trochę problemów nastarcza mi obecnie widoczność klas/pól dla CoFoJa w intellij. Classpath (dla procesora) zdaje się być ustawiony poprawny oraz jego klasa jak i inne opcje też jednak nie dochodzi do poprawnego przeparsowania wszystkich reguł. No cóż, może jutro się uda – tymczasem odsyłam do poradnika dla użytkowników Eclipse gdzie to członek społeczności sprawnie poradził sobie z tym problemem :-)

Trzeźwe spojrzenie: „Czy obecnie warto?

Pozostaje pytanie… Czy warto się zainteresować CoFoJa jak i samym DBC? Pytanie jest chyba równie ogólne jak „czy warto meta-programować?” także wprost odpowiedzi nie udzielę. Miejmy jednak na uwadze że jak na razie używanie CoFoJa nie jest zbyt wygodne a adnotacje można by jeszcze trochę poszlifować. Trzeba by jeszcze rzucić okiem jak stoimy z integracją tego z Maven – aby normalnie testując bądź klikając sobie po projekcie te kontrakty mogły się przydawać. Sama idea jest ciekawa i jakby integracja z narzędziami była wygodniejsza – a może od razu pluginy do IDE – można by się nad tym porządniej zastanawiać. Jak na razie projekcik odkładamy ten projekt spokojnie na półkę „worth watching” i liczymy na rychłe wydanie 2.0. :-)

PS: Jeżeli interesują Cię takie jak i inne ciekawe metodyki i sposoby tworzenia pięknego, czystego kodu, zapraszam serdecznie na co 2 tygodniowe spotkania SCKRK gdzie obecnie dyskutujemy w formie „reading club” nad Domain Driven Design :-)

XSolve @ JavaCamp #5

Author: Konrad Malawski (Konrad Malawski) | grudzień 16th, 2010
avatar

Niecały miesiąc temu odbył się, piąty już z kolei, JavaCamp w Krakowie. JavaCamp to seria „większych” spotkań organizowany przez Polish Java User Group. Naszym pomysłem na spotkania JUGowe jest jak widać „rzadziej, a więcej”, trochę inaczej niż pozostałe JUGi które zazwyczaj spotykają się regularnie, za to na jedną prelekcję. W związku z tym, że obecnie pracuję w XSolve wpadliśmy (piszę „my” jako członek PJUGa jak i zespołu XSolve) na pomysł zasponsornowania tego wydania JC, a teraz nareszcie możemy pochwalić się umieszczonymi nagraniami z spotkania na parleys.com (kto nie zna – niech wejdzie i pozna).

Na pierwszy ogień poszedł Łukasz Lenart, który opowiedział troszkę o byciu lepszym programistą, miękkich umiejętnościach oraz na przykład Zen To Done lub znanym Pomodoro. Prezentacja bardzo przyjemna i omawiająca rzeczy „wydawałoby się że oczywiste”. Problem leży w tym że czasami (hah! A może nawet „często”?!) o tych rzeczach najprostszych się zapomina wpadając w wir ślepego klepania kodu… ;-)

Drugą prezentację prowadziłem ja, a temat był oczywiście jednym z dla mnie obecnie bardzo (bardzo) istosnych: rozproszone systemy kontroli wersji, a konkretniej: git. Była to moja pierwsza prezentacja przed „większą” publicznością i mimo drobnych komplikacji („demo syndrome”… ;-)) przekazałem uczestnikom dość dobrą dawkę użytecznych informacji na temat git’a, co może potwierdzić wzmożone zainteresowanie i migracje wśród znajomych od czasu tej prezentacji…

Po przerwie na pizzę ufundowaną przez XSolve, do prezentowania przystąpił Łukasz Żmudziński. Proszanym tematem był projekt Lombok – który swoją drogą niedługo później autorzy bardzo wesoło prezentowali na niemieckim Devoxx :-). Lombok za cel stawia sobie zdjęcie z programistów Java smętnego klepania tak zwanego boilerplate („ten szum który musimy naklepać w każdym POJO etc etc”).


Ostatnia prezentacja tego dnia poruszyła tematykę również mi bardzo bliską i ciekawą: TDD, na przykładach. Łukasz Czerpak pokazał na licznych przykładach jak powinny wyglądać dobre testy. Jego przykładowe testy (których było mnóstwo) były dla mnie dość ciekawe jako, że z EJB większej styczności dotychczas jeszcze nie miałem.


To by było na tyle nagrań z piątej edycji JavaCamp’u. Zapraszamy na przyszłe (już niebawem) oraz oczywiście na nadchodzący wielkimi krokami GeeCON. :-) W razie zainteresowania innymi nagraniami i przyszłymi spotkaniami Polskiego JUGa, zapraszamy na java.pl oraz nasz kanał na parleys.com… :-)

Konfiguracja projektu w symfony pod Test Driven Development

Author: Wojtek Sznapka (wojciech.sznapka) | październik 22nd, 2010
avatar

W projektach symfony, korzystając z wbudowanego mechanizmu do testów jednostkowych (lime), można łatwo programować w oparciu o nurt Test Driven Development (TDD).

Aby przygotować środowisko do TDD wystarczą trzy kroki:

  1. Konfigurujemy połączenie do testowej bazy, którą będzie sqlite przechowywane w pamięci. W pliku config/databases.yml dopisujemy:
  2. Tworzymy dane testowe, tzw. fixtures, które umieszczamy w folderze test/fixtures (należy go stworzyć ręcznie). Celowo nie umieszczamy danych w data/fixtures, gdyż tam powinny znaleźć się testowe dane, które mogą być użyte np. podczas prezentacji systemu. Jeśli chcemy zachować kolejność danych, możemy ponumerować pliki yml, np.
  3. Tworzymy plik bootstrap dla testów opartych o bazę danych (test/bootstrap/model.php). Plik ten stworzy strukturę tabel na podstawie modelu i załaduje je do bazy oraz wprowadzi dane testowe (fixtures). „Dziedziczy” on pewne ustawienia z bootstrapu unit.php. Trzeba z niego korzystać zawsze, gdy przychodzi potrzeba odwoływania się w testach do bazy danych.

Następnie uruchamiamy ./symfony test:unit i podziwiamy, jak nasze testy przechodzą w stu procentach :-)
Powyższa konfiguracja była testowana dla symfony 1.4 z doctrine 1.2