Rysownicy szkicują. Pisarze robią konspekty. Naukowcy stawiają hipotezy. Co robią programiści? Zwykle idą na żywioł. Strach przed waterfallem poszedł tak daleko, że przestaliśmy planować cokolwiek. Tymczasem dobrze jest mieć mechanizm, który będzie co kilka minut przypominał nam, gdzie jest nasz cel. Tym właśnie jest test driven development.
Skoro to czytasz, to zapewne termin “test driven development” obił Ci się o uszy. Może nawet masz za sobą (niekoniecznie udane) pierwsze podejście. I drugie. I trzecie… Może zastanawiasz się jak robić to dobrze, albo po co w ogóle to robić. I tu wchodzi migawka.it – cała na biało.
TDD albo APAP – wybór należy do Ciebie.
TDD jest wyrazem akceptacji sposobu, w jaki działa ludzki mózg – jego mocnych i słabych stron – oraz rozumieniem, że tak jak niewłaściwe korzystanie z młotka skończy się bólem palca, tak nadwyrężanie mózgu skutkuje bólem głowy.
Spójrz na swoje aktualne zadanie. Nieważne jak jest małe. Mózg jest dygresyjny i lubi się na czymś zafiksować albo popłynąć, jeśli nic go nie pilnuje:
Miałem to już skończyć, ale od 3 godzin próbuję sprawić, żeby pętla odpalana raz do roku działała 10 milisekund szybciej… Co ja miałem…? Moment, jak ja się znalazłem w tym kodzie i dlaczego jest trzecia w nocy? O, tu można poprawić wcięcie.
Wiem, trochę koloryzuję, ale jednak brzmi znajomo, co nie?
Kojarzysz jak Scrum rozbija Twój projekt na dwutygodniowe cykle, z których każdy ma (no dobra, w idealnych warunkach 😉) jasno określony, osiągalny cel? TDD robi dokładnie to samo, tylko w skali minut. Dzięki temu Twoja głowa co chwilę naprowadzana jest z powrotem na wyznaczony cel, a Ty możesz skupić się na pisaniu dobrego kodu, zamiast na pamiętaniu co masz do zrobienia i gdzie jest paracetamol.
A to w testach nie chodzi o błędy?
Zauważ, że nie wspomniałem ani słowem o zapobieganiu błędom. Otóż to dzieje się niejako przypadkiem i to na dwa sposoby.
Pierwszy to zapobieganie regresom. Test da nam znać, kiedy coś przestanie działać zgodnie ze specyfikacją nim wyrażoną. Ważne by pamiętać, że „przestało działać” nie zawsze znaczy “popsute”. Czasem coś przestaje działać, bo nie jest potrzebne albo zmieniły się wymagania biznesowe i to jest OK.
Drugi sposób to architektura i czytelność kodu, która wynika z programowania sterowanego testami. TDD pomaga nam skupić się na tym, jak kod będzie używany (na API i interfejsach) i w naturalny sposób prowadzi nas do SOLID, czystej architektury i programowania funkcyjnego. A czytelny, zrozumiały i pozbawiony przypadkowej złożoności kod trudniej jest popsuć.
Pisanie unit testów jest bardziej aktem projektowania niż weryfikacji
Robert C. “Uncle Bob” Martin
Lubię mówić, że dobra architektura jest tam, gdzie TDD nie wkurza. To jak kontrolka ESP w samochodzie – jeśli się zapala, to znaczy, że niekoniecznie jedziemy tam, gdzie byśmy chcieli.
Wykonywalna specyfikacja
I wreszcie TDD jest sposobem na stworzenie dokumentacji, która nie tylko opisze cały nasz projekt, z przykładami użycia każdej jego części, ale sama zadba o własną aktualność. A to wartość sama w sobie, bo od braku dokumentacji gorsza jest tylko błędna dokumentacja.
Co nas czeka?
W tej serii postaram się wytłumaczyć nie tylko jak pisać testy, ale przede wszystkim dlaczego i jakie cele powinny nam w tym przyświecać. Spróbuję usystematyzować Twoje myślenie tak, żeby TDD pomagało Ci w pracy i stało się równie naturalne jak szkicowanie dla rysownika.
Model pracy w TDD
Zaczniemy od poznania koncepcji cyklu pracy i dowiemy się po co nam on. Skonfrontujemy ze sobą różne cykle pracy na różnych poziomach projektu i odkryjemy fraktalną naturę dobrych pomysłów.
Cykl pracy: Plan, Do, Study, Act
W kontekście TDD wprowadzimy cykl PDSA i kompletnie olejemy standardowo stosowany Red → Green → Refactor. Oczywiście z uzasadnieniem 😉. Omówimy ze szczegółami co robić na każdym z jego etapów.
Praca z kodem legacy
Wejdziemy w stan wojny, obrócimy PDSA o 90 stopni i odkryjemy pętlę OODA (Observe→ Orient → Decide → Act), którą piloci myśliwców stosują do walk powietrznych. Użyjemy jej do pokonania potężnego przeciwnika – Kodu Legacy.
Testy regresyjne
Wrócimy na chwilę do koncepcji testów regresyjnych i porozmawiamy o usuwaniu testów i będziemy się cieszyć, że popsuliśmy stare testy.
Wykonywalna specyfikacja
Popatrzymy czego możemy dowiedzieć się z dobrego zestawu testów i powiemy sobie kilka słów o BDD – behavior driven development.
Czym jest unit i testowalność kodu
Spojrzymy na źródło wszelkiego zła w pierwszych podejściach do TDD – błędne rozumienie koncepcji jednostki w teście jednostkowym. Zobaczymy jak testowalność kodu łączy się z rozdzieleniem odpowiedzialności, enkapsulacją a nawet programowaniem funkcyjnym.
Architektura jako odruch bezwarunkowy
Zobaczymy jak, w całkowicie naturalny sposób, programowanie sterowane testami doprowadzi nas do tego, co czytelnicy Migawki lubią najbardziej (albo czego mają już serdecznie dość 😀), czyli Czystej Architektury.
Czy TDD nas spowalnia?
Na koniec zastanowimy się, czy to, czego nauczyliśmy się na przestrzeni całej serii przyspieszy czy spowolni naszą pracę. Odpowiedź… nie jest oczywista 😉.
Mam nadzieję, że zostaniecie ze mną do samego końca serii, polecicie znajomym i dacie jakże cenny feedback 🙂. Dalej pozostanie Wam już tylko stosować TDD w codziennej pracy i cieszyć się z pancernego kodu, zrozumiałej dokumentacji i osiąganych jeden za drugim deadline’ów 🙂.
.
Funkcja trackback/Funkcja pingback