Test-Driven Development ma niezaprzeczalnie bardzo pokaźną liczbę zalet, jednak jednym z problemów stojących na przeszkodzie we wdrożeniu i stosowaniu tej techniki jest fakt, że pisanie testów jednostkowych wymaga większego nakładu czasowego programisty. Nie licząc czasu na zmianę sposobu myślenia oraz naukę zespołu, pisanie testów jednostkowych może trwać nawet dwukrotnie dłużej niż w sposób “beztestowy”.
Warto więc zadać podstawowe pytanie: Czy TDD się opłaca?
Spójrzmy na TDD okiem biznesowym…
Barry Boehm we wczesnych latach 80. ubiegłego wieku opublikował statystyki, z których wynikało że koszty zmian w oprogramowaniu oraz łataniu dziur w aplikacjach rosną w znaczący sposób z czasem życia programu. Analiza amerykańskich korporacji, m.in. Hewlett-Packard, IBM, Hughes Aircraft i TRW, wskazywała że cena zmian w oprogramowaniu rośnie wraz z przejściem do kolejnej fazy iteracyjnego modelu kaskadowego (tak, tak – waterfall):
Zmiana kodu po fazie analizy, tworzenia kodu, przetestowania go oraz oddaniu w ręce klienta może być nawet dwustukrotnie (!!) wyższa niż na etapie zbierania wymagań biznesowych. Oczywiście, wartość ta zależy od wielu czynników, takich jak na przykład wielkość i złożoność projektu. W pesymistycznym scenariuszu, koszt zmian rośnie wykładniczo. Zobrazujmy taki scenariusz przykładem: Jedna strona wymagań biznesowych może przełożyć się na 5 stron diagramów, 500 linii kodu, 15 stron dokumentacji oraz kilkadziesiąt przypadków testowych. W waterfallu kaskadowane są zatem nie tylko fazy procesu, ale też problemy…
W jaki sposób możemy zredukować koszty zmian w projekcie programistycznym? W 1999 r. Kent Beck zaproponował spłaszczenie powyższego wykresu przy zastosowaniu autorskiej metody programowania ekstremalnego (XP). Składniki, które wpływają na elastyczność kodu i relatywnie niski koszt zmian to:
Dobrze, mamy już oparcie o statystyki z waterfallowych lat 80. oraz przykład redukcji kosztów zmian przy pomocy paradygmatu ekstremalnego programowania. To jednak zbyt mało żeby jednoznacznie potwierdzić lub zaprzeczyć hipotezie o opłacalności TDD. Spójrzmy na problem z szerszej perspektywy.
W roku 2008 pod marką Microsoft Research powstał eksperyment [Nagappan] mający na celu zbadanie zespołów z firmy IBM i Microsoft: czterech, które stosowały TDD oraz czterech z grupy kontrolnej, którą stanowiły zespoły jak najbardziej zbliżone do grupy eksperymentalnej, lecz oczywiście nie stosujące TDD. Eksperyment przeprowadzano na “żywych” projektach, aktualnie pisanych przez dane zespoły.
Wszystkie cztery przypadki użycia dobrano w ten sposób, aby zagwarantować zróżnicowanie w obrębie eksperymentu. Zespoły miały:
Wnioski z eksperymentu były interesujące:
Do innego eksperymentu [Boby] zaproszono 24 doświadczonych programistów, którzy mieli napisać mały programik w Javie. Programowanie odbywało się w parach, gdzie jedna para pisała kod w oparciu o TDD, a druga (oczywiście) nie-TDD. Testy przeprowadzono w trzech różnych firmach. Do weryfikacji jakości przygotowano 20 testów penetracyjnych (black box).
Okazało się, że:
Jedną z najciekawszych prac nt. TDD jest meta-analiza 27 prac naukowych i 3 innych meta-analiz o tematyce TDD [Rafique]. Dokonano podziału prac naukowych ze względu na eksperymenty wykonane w środowisku akademickim oraz branżowym.
Z ogólnie dostępnych prac naukowych odfiltrowano te, których wiarygodność była niska ze względu na:
Nie rozpartywano także prac, w których wyniki opierały się o rezultaty już istniejących prac naukowych. Wyniki analizy przedstawiają się następująco:
Czy TDD zawsze się opłaca? Wiemy z wielu wiarygodnych źródeł, że TDD łączy się z wyraźnie wyższą jakością a w rezultacie mniejszą ilość defektów. Narzut czasowy na napisanie testów jednostkowych szybko się zwraca, gdyż koszt późniejszych zmian bez automatycznych testów jest znacząco wyższy, a w pesymistycznych scenariuszach może rosnąć wykładniczo.
TDD jest bardzo dobrze zbadany w językach obiektowych i tam zwrot z inwestycji dla projektów podparty jest dużo wyższą jakością. Brakuje jednak odpowiedniej ilości prac i przypadków użycia dla języków nieobiektowych oraz ekosystemów z wyłączną warstwą testów funkcjonalnych i BDD. Nic nie stoi jednak na przeszkodzie, aby opłacalność dodatkowych warstw testowych badać empirycznie na przykładzie swojego projektu. Z mojego doświadczenia i obserwacji wynika, że warstwę testów jednostkowych warto rozszerzyć (lub taką opcję rozważyć) o testy integracyjne, ATDD lub/i BDD.
Część I: Testy jednostkowe – wstęp