Zalety programowania sterowanego testami
Oto kilka zalet, które według mnie wynikają z programowania sterowanego testami.
1. Testy jako specyfikacja
Pisząc
testy przed realizacją,
budujemy swojego rodzaju specyfikację tego, co ma być zrobione.
Zastanawiamy się, jakiej metody oczekujemy i jakie powinna ona
przyjmować parametry. Musimy również określić z kim będziemy
współpracować, aby wykonać zadanie. Te wszystkie informacje są zawarte
w teście. Dzięki temu możemy skupić się na interfejsie klasy a nie na
jej realizacji. Rozpoznanie i zdefiniowanie zależności umiejscawia
klasę w systemie. Znając zależności możemy redukować ich ilość, aby
uczynić system spójnym (ang. high cohesion) i dążyć do luźnych powiązań
(ang. low coupling) [1].
2. Testy jako wyrocznia
Gdy
już mamy zestaw testów, zabieramy się do implementacji. Zestaw testów
jest wyznacznikiem poprawnej realizacji funkcji. Jego wykonanie
przechodzi wtedy i tylko wtedy, gdy funkcja jest poprawnie
zrealizowana (zakładając, że zestaw ten jest wystarczający). Dzięki temu programista w krótkim czasie może sprawdzić,
czy wykonał już swoje zadanie i być pewnym, że wykonał je prawidłowo.
3. Testy jako dokumentacja
Zestaw
testów może służyć również jako dokumentacja. Każdy test jest
specyfikacją pewnej operacji i dostarcza przykładu jej wykorzystania. W
metodyce XP nie tworzy się dokumentów projektowych ani innej tego typu
dokumentacji. Praktycy uważają, że testy, czyli przykład użycia kodu,
są wystarczającą dokumentacją. Dokumentacja nie jest już statycznym
dokumentem, który dezaktualizuje się zaraz po tym, jak zostanie
napisany. Testy aktualizowane są wraz ze zmieniającym się projektem i
wymaganiami – są dynamiczne. Dzięki temu także dokumentacja jest
dynamiczna i zawsze aktualna.
Z drugiej strony, jeśli mamy jakiś
obcy komponent, którego jeszcze nie znamy i chcielibyśmy poznać, jak on
działa, to możemy go wyprobować, pisząc dla niego testy. W taki sposób możemy zobaczyć, czy jego działanie jest zgodne z naszymi
oczekiwaniami, a poza tym możemy dowiedzieć się, jak on działa.
4. Testy jako pierwszy klient
Programowanie
sterowane testami sprawia, że tworzone komponenty łatwo ponownie
używać. W programowaniu obiektowym jednostką ponownego użycia jest
klasa. Testy jednostek, gdy pisane przed realizacją danej klasy, są jej
pierwszym klientem. Drugim klientem jest inna klasa, która będzie ją
wykorzystywała w wytwarzanym systemie. Mamy zatem dwóch klientów. Ich
istnienie daje podstawy, aby przypuszczać, że realizowana klasa daje
się łatwo ponownie wykorzystać. Zauważmy, że z jednej strony klasa ta
ma współpracować z pewnymi klasami systemu, a z drugiej strony testy
jednostek wykorzystują ją w oderwaniu od tych klas. To potwierdza
przekonanie, że klasa ta daje się z powodzeniem używać w zupełnie innym
systemie niż ten, dla którego została stworzona.
5. Testy jako siatka bezpieczeństwa dla refaktoryzacji
Jest
jeszcze inna zaleta dysponowania zestawem testów. Dzięki nim
programiści nabierają pewności swoich do działań. Są pewni, że
przekształcenia, które wykonują, niczego nie psuja (chociaż mogą
wprowadzać nowe błędy, które nie zostały ujęte w testach). Niemniej
jednak umożliwią one z większą pewnością wprowadzać zmiany w kodzie bez
obawy o skutki.
Drugim aspektem jest użycie testów w wypadku
pojawienia sie błędu, który trzeba poprawić. W tym wypadku mamy dwie
możliwości. Możemy uruchomić aplikację w trybie odpluskwiania i krok po
kroku analizować błędny scenariusz, aż zlokalizujemy błąd. Z drugiej
strony moglibyśmy napisać test, który nie przechodzi, gdy istnieje
usterka, ale przechodzi po jej naprawieniu. Takie podejście dostarczy
nam wyznacznika, dzięki któremu będziemy wiedzieli, czy dana usterka
została naprawiona, czy nie.
[1] Larman C.: Applying UML and
Patterns: An Introduction to Object-Oriented Analysis and Design and
the Unified Process. Upper Saddle River, NJ. Prentice Hall, 2001.