Archive for October, 2009

TDD na żywym organiźmie

Jakiś czas temu próbowałem nauczyć się stosowania TDD na “testowym” projekcie. Niestety testowanie kontrolerów i widoków wydało mi się zbyt problematyczne.

Pod wpływem zgłębianiu tematu przy okazji pisania pracy magisterskiej zacząłem też myśleć o tym, że pokrycie kodu testami w 100% może nie być możliwe – szczególnie w przypadku, gdy technika ta nie jest znana zespołowi. Jako, że podoba mi się podejście “sztuki rzeczy możliwych” – pomyślałem, że przynajmniej trzeba mieć unit testy w miejscach krytycznych. Zakładając, że stosujemy uczciwie podejście fat model, skinny controller – większość krytycznych elementów znajduje się właśnie w modelach.

Modele łatwiej jest testować niż “wyższe” warstwy modeli MVC, więc tym bardziej wspomniana zasada wydaje się być ważna.

Ostatnio w projekcie natknęliśmy się na ciekawy przypadek. W bazie istniały obiekty, do których mogli być przypisani właściciela (wiele właścicieli do wielu obiektów):
Object habtm Owner
Dodatkowo to przypisanie było ograniczone czasowo, tzn.:
Object1 jest powiązany z OwnerA od 15 marca 2009 do 31 lipca 2009
oraz
OwnerB jest powiązany z Object1 od 01 czerwca do nie_wiadomo_kiedy (to znaczy, że aktualnie jest przypisany, ale nie wiadomo, kiedy ten stan się zakończy, nazwę to przypisaniem otwartym na potrzeby tego wpisu).

Możliwa była sytuacja, gdy Owner1 jest przypisany do ObjectA tak jak w przykładzie powyżej i od 01 listopada do nie_wiadomo_kiedy też z ObjectA.

Nie zagłębiając się więcej w szczegóły dodam tylko, że potrzebna była metoda, która odpowie na pytanie “czy dla danego Object, Owner i danych dat początkowej i końcowej mogę dodać powiązanie?”.

Członek zespołu zabrał się za to zadanie i po jakimś czasie skończył. Jednak wyznał szczerze, że nie jest pewien, czy ten fragment dobrze działa. Problem zdawał się rosnąć w momencie używania przedziałów otwartych z prawej strony. Pomyślałem, żeby zamiast ślęczeć nad kodem przez najbliższą godzinę i ręcznie testować przypadki – pobawić się w TDD.

Może nie bardzo podobało się to programistce, która nad kodem aktualnie pracowała, ale kod ten został wywalony – łatwiej jest stosować TDD gdy zaczyna się od zera (przynajmniej na moim, bardzo początkującym poziomie). Pracowaliśmy od teraz wspólnie nad kodem.

Podejście było takie, żeby dodawać coraz to kolejne kombinacje testów – dodanie powiązania z konkretnymi datami gdy w bazie istnieje przypisanie zamknięte, próba dodania przypisania otwartego gdy w bazie jest zamknięte i wszystkie możliwe kombinacja. Wyszło ich około 20*.

(*) możliwe, że niektóre przypadki są bardzo podobne i się dublują – chciałem jednak mieć je wymienione explicite

Proces wyglądał następująco:
1. test przypadku
2. fail testu
3. poprawa testowanej funkcji
4. pass wszystkich testów
5. test dla następnego przypadku
6. fail testu

Gdy była możliwość dokonywany był refaktoring testowanej funkcji, a raz nawet refaktoring samych testów.

Jaki był bilans tego działania? Pomyślmy jak wyglądałoby życie, gdybyśmy podeszli do tego problemu “po staremu”

Zajęło by to jakąś godzinę, mielibyśmy “dość mocne przekonanie”, że metoda spełnia wymagania. Jednak raczej staralibyśmy się uniknąć dotykania tego fragmentu w przyszłości, bo to oznaczałoby przeprowadzenie testów ręcznych od początku.
Nie posiadalibyśmy jednak twardych dowodów na to, że wszystkie testy zostały przeprowadzone – tylko silne poczucie, że “raczej tak”.

Jak to wyglądało z TDD?
Zajęło to około 4 godzin. Mamy twarde dowody na to, że wszystkie przypadki, które wymyśliliśmy są testowane. Mogą być przetestowane w każdym momencie. Znaleźliśmy błąd polegający na niesprawdzaniu, czy data startowa powiązania jest mniejsza niż końcowa. W efekcie tych działań otrzymaliśmy bardzo przyjemną funkcję logiczną, którą z przyjemnością wrzuciliśmy do funkcji beforeValidate testowanego modelu, aby żaden zapis nie mógł się odbyć przy nieodpowiednich danych.
Gdyby klient zaskoczył nas zmianą wymagań dot. zasad, które zaimplementowaliśmy – bez większych problemów można zabrać się za ich modyfikację pilnując, żeby dotychczasowe testy, które jeszcze są aktualne, przechodziły.
Jako bonus – jeden z członków zespołu dowiedział się czegoś więcej o TDD.

Dlatego jeśli myślisz, że TDD jest przerażające, bo wymaga pisania testów wszędzie (jak ja myślałem na początku), to możesz spróbować stosowania TDD tylko w krytycznych miejscach. Najczęściej w modelach. Kto wie, może po jakimś czasie, gdy oswoimy się z tą techniką pojawi się jakaś koncepcja, żeby zastosować TDD w kontrolerach a później widokach?

No Comments

Gracze pełni idealizmu

Przeczytałem właśnie o polskiej ekipie, która wygrała ligę Call of Duty i zdecydowała się przekazać nagrody dzieciakom z domu dziecka.

Myślę, że mimo iż ten blog nie traktuje o graniu, warto poświęcić chłopakom wpis. Powinni się czuć dobrze, bo mają powód.

No Comments

Pierwsze wrażenia z Google Wave

Po pierwsze – programiści czy to z google czy nie nie tracą dobrego humoru:

Nic dziwnego, że do tej aplikacji jest na razie ograniczony dostęp

Nic dziwnego, że do tej aplikacji jest na razie ograniczony dostęp

Po drugie – bardzo fajnie jest odpowiedzieć na konkretną wiadomość wysłaną do Ciebie. Te wiadomości wyglądają jak posty na forum. Różnica jest taka, że tworzą one drzewo. Odpowiedzieć możesz w dowolnym miejscu. Zatem w ramach jednego wave’a można prowadzić kilka równoległych dyskusji.
Dodatkowo te odgałęzienia mogą być dyskusją, którą widzą nie wszyscy członkowie całego wave’a

Przykładowy wave

Przykładowy wave

Oczywiście nie jest to nic co nie byłoby pokazane na prezentacji, o której było tak głośno ;)

Co z rzeczy niezaprezentowanych na filmie?

Przede wszystkim po kilku minutach rozmowy z kimś kto jest online – zaczynasz mieć wrażenie, że pisząc tradycyjnego maila jego odbiorca na bieżąco widzi jak go redagujesz. To niesamowite wrażenie. Tak działa wave – gdy odpisujesz komuś działa to jak czacie.
Kilka chwil takiej rozmowy. Żegnasz się z rozmówcą. Zabierasz się za zwykłego maila, piszesz, piszesz. Kasujesz jakieś zdanie, które raczej powinno być inne i… łapiesz się na tym, że odbiorca już go musiał zobaczyć. A po chwili “nie, czekaj!” przecież to zwykły mail… “uff” ;)

W wave chyba nie można tej funkcji jeszcze włączyć. Przy odpowiedziach jest opcja “draft” ale nie można jej zaznaczyć. Myślę, że przydałaby się możliwość ustawienia tego trybu na stałe ;)

Tak, czy siak – jest to naprawdę nowa forma komunikacji, która może zmienić wiele dotychczasowych sposobów tego jak się porozumiewamy:

- z tradycyjnego e-maila zostało właściwie tylko podejście w którym różne serwery wave’owe mogą się porozumiewać (czyli nie ma być sytuacji jak z IM, że ktoś jest w innej sieci więc z nim nie pogadamy)
- z forów (czy z Gmaila) mamy wątkowanie wiadomości
- z IM mamy rozmowę na żywo, która ma jednak dopalacze: użytkownik nie widzi wiadomości po tym jak klikniemy “wyślij” – widzi ją od razu. No chyba, że rozmawiasz z kimś z Indii* – to nie tak znów od razu :D

* przy tej okazji pozdrowienia dla nowego kolegi Azmatha

Ok, dość tego chwalenia się :P
Teraz mam niespodziankę. Zostały mi do wysłania dwa zaproszenia do google wave. Jeśli nie możesz się doczekać – możesz wziąć udział w mini konkursie: jeśli interesuje Cię ta nowa zabawka od wujka Google’a napisz o tym na swoim blogi i walnij pingback do mnie. Wśród wszystkich pingbacków całkowicie losowo wybiorę dwóch szczęśliwców, którym wyślę zaproszenie.

//Edit: dodam jeszcze, że konkurs będzie trwał do 31 października do północy. Po tym terminie wylosuję dwie strony i spróbuję się skontaktować z ich właścicielami, aby otrzymać adres e-mail na który wysłać zaproszenia :)

4 Comments