Już od dłuższego czasu przymierzałem się do poznania tej techniki tworzenia oprogramowania. Zawsze gdy tworzyłem oprogramowanie pisałem jakąś funkcjonalność i gdy uznałem, że to co napisałem działa przynajmniej w części tak jak powinno zabierałem się do testowania. I testowałem, testowałem, debugowałem, testowałem… Czasami na przetestowanie i poprawę, często głupich, błędów potrzeba było o wiele więcej czasu niż na „pierwszą implementację”(która zawsze wydaje się najtrudniejsza). Postanowiłem w końcu „coś z tym zrobić”. A nuż się uda i testowanie nie będzie takie męczące?
Ogólnie biorąc praca w ten sposób polega na pracy w małych cyklach:
Ważne jest, aby w cyklu implementować tylko małą funkcjonalność, by cykl nie trwał bardzo długo. Dość dokładnie jest to opisane na angielskiej Wikipedii.
Testy w TDD są tzw. testami jednostkowymi(a przynajmniej powinny być), czyli testują tylko JEDNĄ JEDYNĄ rzecz. Z założenia nie powinny sprawdzać działania np. kilku funkcji. Lepiej napisać więcej testów które są krótsze niż jeden dużo. Ułatwia to wychwytywanie błędów, podnosi czytelność kodu i ułatwia późniejszą jego rozbudowę. Gdy mamy dużo podobnych testów dobrze jest wyodrębniać część wspólną dla nich wszystkich. Większość frameworków udostępnia tzw. fixture – ułatwiają „wyjęcie” inicjalizacji do osobnych metod.
Na początku zdobywania informacji byłem przekonany, że taka technika sprawdza się tylko w aplikacjach biurowych i ewentualnie stronach. Nie miałem pomysłu co można w ten sposób testować. Okazuje się, że można prawie wszystko! Np. czy postać dostaje powerupy, czy do ekwipunku dodawany jest jakiś przedmiot, czy, jeśli dodamy drugi taki sam(np. eliksir) to nie dodaje się jako osobna pozycja a zwiększa zapas już istniejącego, czy drzwi się otwierają tylko jeśli mamy klucz itp. Dużo w zrozumieniu tego pomógł mi artykuł Games From Within – Stepping Through the Looking Glass: Test-Driven Game Development(Cz. 2, Cz. 3). W przystępny sposób pokazał mi, że rzeczywiście można testować prawie wszystko.
Dość teorii – czas na praktykę(której mi brak, niestety). W .NET mamy co najmniej kilka frameworków do testów jednostkowych: nUnit, mbUnit czy Microsoftowy MSTest. Ja jedynie miałem okazję „testować”(odpalić przykładową aplikacje i skrobnąć prościutki test) nUnit i… to nie jest takie złe
Kingdoms Clash.NET będzie pierwszym moim projektem, w którym użyję unit testów i TDD. Co z tego wyjdzie – czas pokaże. Mam nadzieję, że nie porzucę tej idei zaraz na początku tylko dociągnę ją do końca
Jeśli planujesz sensownie uprawiać TDD, nie obejdzie się bez frameworka do mockowania, dzięki któremu będziesz mógł zasymulować spodziewane zachowanie tej części aplikacji, która nie jest objęta testem. Popularnymi darmowymi narzędziami służącymi do tego celu są Moq (http://code.google.com/p/moq) i Rhino Mocks (http://www.ayende.com/projects/rhino-mocks.aspx).
Na blogu Procenta dostępny jest cykl wpisów poświęcony wykorzystaniu mocków i Rhino Mocks w pisaniu testów jednostkowych:
http://www.maciejaniserowicz.com/post/2009/09/29/Spis-tresci-Cykl-o-mock-objects-i-Rhino-Mocks.aspx
Tak, czytałem ten cykl i to głównie dzięki niemu zacząłem poznawać TDD(i mocków – Moq).
Dzięki za linki.
Warto pamiętać jeszcze o jednej rzeczy: o ile testy programowe, niezależnie czy pisane przed czy po, pozwalają zweryfikować poprawność aplikacji, o tyle proces Test-Driven Development (czasami nie bez przyczyny nazywany Test-Driven Design) służy raczej wyłonieniu projektu aplikacji, który pozwala na bezbolesne przeprowadzenie takiej weryfikacji. To zaskakujące, jak często własność ta jest całkowicie ignorowana przez praktyków TDD — ma ona fundamentalne znaczenie.