TDD dla początkujących – co to jest TDD?

TDD jest coraz bardziej popularne wśród osób tworzących programy. Na pewno każdemu obiła się o uszy ta zbitka liter, ale czy każdy wie co ona oznacza?

TDD to skrót od Test-Driven Development, czyli tworzenie programów zorientowane testowo. Brzmi to dziwacznie i chyba nie wiele tłumaczy. Spokojnie, w tym poście postaram się wyjaśnić o co chodzi. Jak zawszę, wszystko zilustruję jasnymi przykładami.

co to jest TDD

Mniej doświadczeni programiści, rzadko testują swój kod. Najczęściej zabieramy się za to w momencie kiedy coś po prostu przestaje działać. Jeżeli kod jest długi a treść błędu mało pomocna i nie możemy znaleźć gdzie coś się popsuło, zaczynamy kombinować. Ja często wstawiałem console.log‚i gdzie popadnie i wyświetłałem wartości różnych zmiennych. Dzięki temu prędzej czy później widziałem w którym miejscu, dzieje się coś niespodziewanego i mogłem poprawić błąd.

To była pewna forma testowania programu, niezbyt optymalna, ale przynosiła efekty. Gdybym używał procesu TDD, wyszukiwanie błędu było by dużo szybsze. Tak naprawdę, pewnie od razu wiedziałbym gdzie jest błąd 🙂 Mało tego, pewnie błąd w ogóle by się w kodzie nie pojawił. A to dlatego, że pierwszą rzeczą którą robi się TDD to tworzy testy.

Proces tworzenia programów techniką TDD, można podzielić na trzy, powtarzające się cyklicznie etapy:

  • Tworzenie testu
  • Pisanie kodu, który przechodzi test
  • Poprawienie kodu

Co to jest TDD? – przykład

Czas na trochę praktyki. Załóżmy, że mam za zadanie stworzenie klasy, której metoda będzie łączyć dwa łańcuchy znaków w jeden. Pierwsze co powinienem zrobić, według metodologii TDD, to stworzyć test. Musi to być coś bardziej, wyrafinowanego niż zwykły console.log, ale nie dużo bardziej :). Stworzę funkcję o nazwie test1:

Ta funkcja sprawdza parę rzeczy i w zależności od wyniku, wypisuje odpowiednią informację w konsoli. Na początku chcę dowiedzieć się czy w taka klasa w ogóle istnieje. Jeżeli tak, badam czy posiada ona odpowiednią metodę. Jeśli i to będzie prawdą, ostatnie sprawdzenie porównuje wynik działania metody ze spodziewanym wynikiem.

Uruchomienie testu w takim stanie spowoduje wypisanie w konsoli:

Ten wynik chyba nikogo nie zaskoczy. Czas dodać odpowiednią klasę do programu. Najpierw stworzę pusty obiekt:

Gdy teraz uruchomię test otrzymam wiadomość:

Idealnie. Kolejny krok to dodanie metody odpowiedzialnej za funkcjonalność programu. Ulepszona klasa concatClass wygląda tak:

Funkcja nie robi nic spektakularnego, po prostu zwraca pustą wartość. Teraz test zwróci mi taką informację:

Mój kod jest coraz bliższy przejścia testu. Teraz zrobię coś co może niektórych zdziwić. W metodologii TDD priorytetem jest napisanie takiego kodu, który przejdzie test. Do dzieła:

Uruchamiam test i voila:

Ktoś może powiedzieć, że to nie ma sensu, w końcu nie to miał robić kod. Miał zwracać połączone dwa łańcuchy znaków a nie łańcuch „hello world”. Tak, ale to nie koniec pracy. Priorytetem jest stworzenie kodu, który przechodzi test. W tym przykładzie, może wydawać się, że nie ma to żadnego sensu. Jednak w prawdziwym życiu, kod ma więcej niż parenaście linijek, wiele modułów i zależności. Zabieg jaki zastosowałem na górze, mówi mi, że pośród tych wszystkich ‚bebechów’ mój kod działa i współgra z resztą programu jak należy.

Mogę przejść do trzeciego kroku TDD czyli ulepszania mojego kodu. Teraz wiem, że jeżeli po jakiejś zmianie, kod przestanie przechodzić test, to problem znajduje się w moim kodzie a nie na zewnątrz. Jest to bardzo przydatna informacja 🙂

Ulepszona klasa do łączenia łańcuchów znaków wygląda tak:

To tylko formalność, ale uruchamiam test aby nie było żadnych wątpliwości. Jak pewnie każdy się spodziewa otrzymuję wynik pozytywny. Mogę zabrać się za dodawanie kolejnego ‚ficzera’. Znów zaczynam od stworzenia testu. Jednak testu już istniejącego, nie usuwam. Za każdym razem, gdy wprowadzę jakieś zmiany przepuszczam mój kod przez wszystkie testy. Dzięki temu, kiedy w programie coś się „pomiesza”, wiem o tym od razu. Do tego wiem dokładnie, w którym miejscu coś się „wykrzaczyło”.

Taki rodzaj testowania nazywa się testowaniem jednostkowym (unit testing), ponieważ testuje on każdą jednostkę/cechę/funkcje programu. Nie jest to jest to jedyny rodzaj testów jaki przeprowadza się w metodologii TDD, ale jest on najważniejszy dla programistów.

Programując w ten sposób po jakimś czasie dysponujemy sporą biblioteką testów, która jest bardzo pomocna podczas modyfikowania tworzonej przez nas aplikacji.

Ale testy miały ułatwiać życie, a wygląda na to, że strasznie dużo z nimi roboty. Ten przykład był banalnie prosty a obsługujący go test zawierał sporo kodu. Co w przypadku, kiedy trzeba przetestować dużo bardziej skomplikowane programy? Wtedy z pomocą przychodzą specjalne narzędzia stworzone po to aby usprawnić testowanie.

W kolejnym poście przedstawię dwa takie narzędzia. Jasmine, framework służący do tworzenia testów, zawierający wiele przydatnych funkcji, porównujących dane lub naśladujących zachowanie przeglądarki, oraz Karma narzędzie do automatycznego uruchamiania testów.

Jeśli nie chcesz przegapić nowych postów, zachęcam do polubienia mojej strony na facebooku. Na bieżąco zamieszczam na niej informacje o nowościach.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *