Czym jest technika TDD i jak wygląda jej cykl życia?
TDD (Test-Driven Development) jest techniką tworzenia oprogramowania (nie jest to technika pisania testów), w której główną ideą jest w pierwszej kolejności pisanie testów do nieistniejącej funkcjonalności, a dopiero potem napisanie kodu implementującego tę funkcjonalność. TDD nie jest jedyną słuszną i dobrą techniką tworzenia programowania. Można pisać testy równolegle z pisaniem kodu logiki biznesowej, można je pisać po implementacji, lecz wtedy nie jest to już TDD. W Test-Driven Development testy piszemy zawsze przed implementacją.
Sebastian Opacki. Java Developer w Onwelo. Absolwent kierunku Informatyka na Uniwersytecie Śląskim w Katowicach. Od niespełna roku pracuje w Onwelo nad projektem Hello Astra, w którym zajmuje się programowaniem nowych funkcjonalności oraz tworzeniem infrastruktury. Prowadzi też wewnętrzne warsztaty dot. testów jednostkowych i ogólnego podejścia do testowania oprogramowania.
Spis treści
Cykle życia TDD
1. Napisanie przypadku testowego
Na tym etapie musimy wiedzieć, co chcemy przetestować i czego oczekujemy od testowanej funkcjonalności. Dzięki temu również możemy sprawdzić, czy dokładnie rozumiemy logikę biznesową, a zapewne zdarzyło Wam się programować „w ciemno”. Dobrym pomysłem jest pisanie testu, kierując się „use case’ami” i „user stories”. Wtedy poprawny i czytelny test stanowi swojego rodzaju biznesową dokumentację, którą można przekazać osobie zajmującej się biznesem w celach sprawdzenia poprawności logiki aplikacji.
2. Uruchomienie napisanego testu
Próbujemy uruchomić nasz napisany test i oczekujemy błędu kompilacji, ponieważ nie ma kodu, który chcemy testować.
3. Napisanie minimalnego kodu do przejścia testu
W tej fazie zabieramy się za pisanie kodu odpowiedzialnego za logikę biznesową, piszemy minimalną ilość kodu, dzięki której po uruchomieniu testu przejdzie on w stan „zielony” – a więc w stan, który oznacza pomyślne przejście testu. Ważna jest tutaj kwestia stworzenia minimalnego zakresu kodu. Nie staramy się pisać całego modułu. Interesuje nas tylko ten kod, który jest pod okiem naszego testu.
4. Refaktoryzacja kodu
Ważne jest, żeby kod testowy był utrzymywany przy takich samych standardach, jak kod produkcyjny. Dlatego w fazie, w której refakturujemy kod, robimy to tak samo starannie dla kodu produkcyjnego, jak i dla naszych testów.
5. Powtarzamy cykl
Tutaj nasz cykl się zamyka. Powtarzamy go, dopóki nie napiszemy wszystkich testów pokrywających logikę biznesową.
Jak długie powinny być cykle TDD?
Kiedy zaczynałem uczyć się tej techniki, jednym z problemów, które napotkałem, była kwestia „długości testów”. Jak długie powinny być testy? Jak duży fragment kodu powinny pokrywać?
Jednym z założeń TDD jest pisanie jak najkrótszych cykli, dużej ilości testów, w której każdy test pokrywa mały wycinek kodu. Zauważyłem w tym podejściu wadę – pisanie bardzo dużej ilości testów jednostkowych było dla mnie uciążliwe. Duża ilość małych testów nie jest zła, wręcz przeciwnie, jednak nie można popadać w skrajność.
Moim zdaniem cykle powinny być na tyle duże, żeby można było łatwo „ogarnąć” to, co się dzieje w przypadku testowym i co ważniejsze – żeby inny programista w łatwy sposób mógł je ze zrozumieniem przeczytać.
Kiedy nie należy stosować TDD?
TDD na pewno nie sprawdzi się w przypadku małych, nieskomplikowanych projektów. Wtedy czas poświęcony na praktykowanie tej techniki mógłby się nigdy nie zwrócić.
Często podczas programowania rozwiązanie problemu, nad którym pracujemy, nie jest oczywiste. W takiej sytuacji najpierw staramy się jak najszybciej napisać kod, dzięki któremu będziemy mieli pewność, że potrafimy poprawnie rozwiązać problem. W takim przypadku na początku nie interesuje nas obsługa błędów tego kodu, przypadki graniczne itd. TDD podczas takiego procesu będzie tylko nas spowalniał. Oczywiście należy pamiętać, żeby po znalezieniu rozwiązania zadbać o refaktor i późniejsze napisanie testów jednostkowych.
TDD nie należy również stosować, w przypadku, kiedy testy są czasochłonne i nie przynoszą dużych korzyści. Nie testujmy kodu trywialnego, który nie wnosi żadnej logiki biznesowej, a jest jedynie „łącznikiem” pomiędzy modułami czy po prostu jest to „boilerplate code”.
Zalety TDD
Podczas tworzenia oprogramowania w sposób klasyczny (najpierw piszemy większy blok kodu, później go testujemy) często w nasz kod wkrada się „bug”, który zostanie odkryty dopiero po jakimś czasie. Wykrycie błędu może trwać godzinę, kilka dni lub nawet kilka miesięcy, kiedy nasz kod już od dawna funkcjonuje na produkcji. Prawdopodobne jest, że jeśli od czasu wprowadzenia błędu do czasu jego znalezienia powstanie dużo dodatkowego kodu, to czas na naprawienie błędu się wydłuży.
Jeśli programujemy zgodnie z TDD, to większość błędów zostanie wykrytych podczas testów przed wprowadzeniem kodu w środowisko testowe lub produkcyjne. Testy je wykryją podczas programowania modułu. W takim wypadku możemy sami naprawić błąd i angażujemy mniej osób do jego naprawy (inni developerzy, testerzy, klient). Dzięki temu oszczędzamy czas. Oczywiście nawet stosując TDD, nie unikniemy pisania błędów, ale zminimalizujemy zakres ich występowania.
Podsumowanie
TDD jest ciekawą techniką tworzenia oprogramowania. Warto się jej nauczyć i spróbować ją wykorzystać w naszych projektach po to, żeby przekonać się, czy przynosi nam ona korzyści. Nie należy jej traktować jako „wyrocznię”, jedyną słuszną technikę tworzenia oprogramowania. Ma ona swoje zalety i wady. Musimy pamiętać o tym, żeby dobierać narzędzia oraz techniki do indywidualnych potrzeb projektu.
Artykuł został pierwotnie opublikowany na blog.onwelo.pl. Zdjęcie główne artykułu pochodzi z burst.shopify.com.