Strefa wolna od botów!
Piszemy my, nie maszyny.

Test Driven Development (TDD) – automatyzacja w tworzeniu oprogramowania

Zróżnicowane wymagania klientów oraz niesamowite tempo zmian w technologii i narzędziach programistycznych wymaga od osób tworzących oprogramowanie olbrzymiej elastyczności i chłonności w zdobywaniu nowej wiedzy. Można powiedzieć, że współczesny programista powinien być zwinny. Uznane i szanowane metodologie tworzenia oprogramowania, w tym Agile, wymagają, aby cały zespół działał zgodnie z nią, a to samo w sobie bywa problemem. Na szczęście jest też rozwiązanie tego dość poważnego problemu – jedną z metodyk Agile można stosować tak indywidualnie, jak i zespołowo – jest to Test Driven Development – TDD.

 

 

Test Driven Development (TDD) – co to jest?

 

TTD należy do grupy metod wytwarzania oprogramowania opartego o programowanie iteracyjno-przyrostowe, czyli takie, które uwzględnia fakt, że wymagania odbiorcy mogą się często zmieniać w czasie realizacji projektu. W roku 1999 Test Driven Development zdefiniował Kent Beck, twórca programowania ekstremalnego i jeden z twórców manifestu Agile. Metodyka ta polega na wielokrotnym powtarzaniu trzech kroków:

  1. Wygenerowanie kodu automatycznego testu sprawdzającego nową, planowaną funkcjonalność. Uruchomienie testu, co oczywiste, daje wynik negatywny.
  2. Implementacja założonej funkcjonalności. Na zakończenie tego etapu, automatyczne testy powinny dać wynik pozytywny.
  3. Refaktoryzacja napisanego kodu tak, aby spełniał przyjęte standardy.

Gdyby pokusić się o bardziej obrazowe analogie, to TDD przypomina strategię „Shift Left” z lat 50. stosowaną w branży motoryzacyjnej, w której skupiono uwagę na tym, aby wszelkie braki i usterki wykrywać na najwcześniejszym z możliwych etapów produkcji.

 

 

Co trzeba wiedzieć o cyklach TDD?

 

Stosowanie cykli Test Driven Development wydaje się na pozór bardzo proste i oczywiste, ale jak zwykle o skuteczności danej metodyki decydują szczegóły i konsekwencja w jej stosowaniu. Przy pisaniu automatycznych testów trzeba pamiętać, że może się zdarzyć sytuacją, w której nie da się jeszcze skompilować kodu testu. Dzieje się tak na przykład w przypadku testowania nieistniejącej jeszcze metody.

Implementacja funkcjonalności nie musi być od razu perfekcyjna. W tym kroku chodzi o możliwe jak najszybsze uruchomienie nowych funkcji tak, aby spełniały one założenia testów napisanych w pierwszym cyklu. Co ważne, dodana funkcjonalność musi przejść wszystkie przygotowane wcześniej testy jednostkowe. Tu nie może być wyjątków ani odstępstw od reguły.

Trzeci etap jest zdecydowanie najważniejszy z punktu widzenia produkcyjnego. W procesie refaktoryzacji kod jest poprawiany i oczyszczany w taki sposób, aby bez zmian pozostawić jego funkcjonalność. W tym cyklu można tworzyć nowe metody, które usuną powielony kod, czy nowe klasy odpowiadające za wydzielony fragment zadań klasy macierzystej. Pominięcie tego etapu lub jego powierzchowne potraktowanie skutkuje powstaniem kodu trudnego w utrzymaniu, gdzie nawet proste zmiany mogą wymagać bardzo dużo czasu.

O skuteczności Test Driven Development decyduje adekwatny do konkretnej sytuacji dobór długości cyklów. Innymi słowy – jak duży fragment kodu powinno się testować pojedynczym testem? Na tak postawione pytanie nie ma gotowej odpowiedzi. Praktyka pokazuje, że głównie decyduje doświadczenie programisty i jego osobiste obycie z kodem. Krótkie cykle i bardzo duża liczba testów z czasem może dać na tyle pewności i swobody dla programisty, że cykle TDD można wydłużyć. Jednak zawsze trzeba pamiętać o uruchamianiu wszystkich testów jednostkowych podczas fazy refaktoryzacji. Drobna zmiana w jednej części programu może powodować błędy w innej, a uruchomienie wszystkich testów pomaga wykryć taką sytuację.

Ostatecznie celem TDD jest szybkie dostarczenie zweryfikowanego kodu funkcjonalności zgodnego z najlepszymi praktykami i standardami tworzenia oprogramowania. Jest szczególnie ważne dla organizacji, które zdecydowały się na automatyzację procesów i zastosowanie technologii, które szybko przynoszą dodatkową wartość biznesową.

 

 

Jakie są zalety i wady TDD?

 

Największą zaletą Test Driven Development jest wykrywanie błędów na maksymalnie wczesnym etapie tworzenia oprogramowania. Programista może samodzielnie naprawić nieprawidłowy kod zanim przejdzie on do środowiska testowego albo co gorsza, do produkcyjnego. Zredukowanie czasu pomiędzy wprowadzeniem błędu a jego wykryciem oznacza, że mniej osób jest zaangażowanych w usuwanie błędów, robi się to taniej i szybciej. Ostatecznie zmniejsza to koszty tworzenia nowego oprogramowania, pojawia się ono zdecydowanie szybciej, a jakość kodu jest wyższa niż przy klasycznych metodach programowania.

Po stronie minusów TDD wypada zapisać trudność w określeniu długości cyklów, liczby niezbędnych testów oraz utrzymaniu balansu pomiędzy pisaniem kodu nowej funkcjonalności a tworzeniem kolejnych szczegółowych testów indywidualnych. Tam, gdzie nie ma jasnej reguły, liczy się doświadczenie i intuicja programisty, a ta czasami bywa zawodna. Duża liczba małych i prostych testów sama w sobie nie jest zła, jednak popadnięcie w skrajność może się przełożyć na spowolnienie realizacji całego zadania.

 

 

Dlaczego warto używać TDD?

 

Test Driven Development pomaga rozwijać i utrzymywać logikę w kodzie i funkcjonalności. TDD wymaga rozpoczęcia testów od najprostszych funkcji, a to sprzyja rozkładowi głównego problemu na mniejsze fragmenty, łatwiejsze do rozwiązania sprawdzenia i weryfikacji. Jednocześnie dzięki TDD rośnie pokrycie kodu testami – buduje to zaufanie do poprawności napisanego kodu. W zasadzie nie powinno spotykać się kodu nie powiązanego z konkretnym zestawem testów. Dodatkową zaletą używania i rozwijania Test Driven Development jest końcowa jakość kodu, a to za sprawą jego każdorazowej refaktoryzacji i optymalizacji w każdym cyklu TDD.

Dzięki konsekwentnemu stosowaniu metodyki Test Driven Development łatwiejsze staje się dodawanie funkcjonalności do kodu – programista ma po prostu pewność, że istniejący już kod jest poprawny, co zawęża pole poszukiwań w przypadku wystąpienia kolejnych błędów w nowych fragmentach kodu. Większa czytelność kodu i opisowe instrukcje testowe zapewniają, że inni członkowie zespołu pracującego nad kodem nie mają żadnych problemów ze zrozumieniem działania poszczególnych metod, nie muszą się domyślać i zgadywać, co programista miał na myśli. W efekcie praca posuwa się naprzód dużo szybciej, z zachowaniem wysokich standardów i jakości oprogramowania. Jest to szczególnie ważne tam, gdzie dokonuje się gruntownej modernizacji oprogramowania biznesowego, a rozumienie istoty kodu jest kluczem do budowy nowych modułów.

Na koniec jednak wypada podkreślić jeszcze jedną wielką zaletę Test Driven Development, czyli elastyczność. TDD można stosować, bez szkody dla całego projektu, do budowy konkretnych modułów, fragmentów kodu, czy funkcji. Zgodnie z regułami TDD może działać tak pojedynczy programista, jak i cały zespół, wszędzie tam, gdzie jest to sensowne i daje widoczne korzyści. TDD świetnie się sprawdza nawet przy budowie dużych, zaawansowanych systemów kompleksowo wspierających procesy zarządzania przedsiębiorstwem.

 

 

TDD kontra tradycyjne testowanie

 

Różnica pomiędzy tradycyjnym testowaniem a Test Driven Development sprowadza się tak naprawdę do kluczowej kwestii czasu pomiędzy powstaniem błędu w kodzie, a jego wykryciem. Przy testowaniu tradycyjnym mogą upłynąć tak samo dobrze godziny, jak i miesiące zanim usterka zostanie wykryta. W tym czasie przybędzie dużo dodatkowego kodu, będzie już działać środowisko testowe lub produkcyjne, a to oznacza, że wzrośnie liczba osób zaangażowanych w naprawę, a i czas usunięcia usterki może być naprawdę długi. W przypadku stosowania TDD testowane jest praktycznie wszystko, szybko i sprawnie. Przy rozsądnym użytkowaniu Test Driven Development czas poświęcany na konstrukcję i stosowanie licznych testów jednostkowych wcale nie musi być dłuższy niż łączny czas testów w klasycznych metodach rozwijania oprogramowania. Jeśli do tego porównania dodać brak wymogu stosowania TDD przez cały zespół programistów, to staje się jasne dlaczego w ostatnich latach Test Driven Development tak zyskał na popularności, szczególnie w dobie transformacji cyfrowej przedsiębiorstw DX – Digital Transformation oraz stosowania rozwiązań chmurowych.

 

 

TDD vs AMDD

 

AMDD to Agile Model Driven Development, czyli zwinne budowanie programów oparte na modelach tworzonych przed napisaniem kodu źródłowego, przy czym się nie generuje większej liczby wersji modelu, raczej tworzy zwinne wersje jednego modelu, które na koniec poprawiają efekt tworzenia oprogramowania.

Różnice pomiędzy TDD a AMDD są istotne i często uchwytne tylko dla osób znających obie metodyki tworzenia oprogramowania. TDD skupia się głównie na implementacji metod, a AMDD na uruchamianiu funkcjonalności. O ile TDD skraca programową pętlę sprzężenia zwrotnego, o tyle AMDD robi to samo, ale z pętlą modelową.

W przypadku Test Driven Development mamy do czynienia z tworzeniem kodu wysokiej jakości i szczegółową specyfikacją jego najdrobniejszych fragmentów. AMDD stawia na jakość komunikacji z programistami i interesariuszami, zajmując się głównie większymi fragmentami tworzonych aplikacji i rozwiązywaniem najważniejszych problemów. Oznacza to także, że TDD stosują przede wszystkim programiści, a AMDD użytkują także analitycy biznesowi, specjaliści od danych operacyjnych i management. W konsekwencji TDD ma bardziej ograniczony zakres zastosowań niż AMDD, nie jest zorientowany na kwestie wizualne i nie zajmuje się zagadnieniami zwinnego skalowania.

 

 

W jakich warunkach nie stosować TDD?

 

Teoretycznie Test Driven Development można stosować zawsze i wszędzie – w końcu kto nie chciałby mieć sprawdzonego i wszechstronnie przetestowanego każdego fragmentu kodu. Jednak z punktu widzenia ekonomiki tworzenia oprogramowania widać, że TDD na pewno nie będzie efektywnym sposobem pracy przy małych i nieskomplikowanych projektach. Po prostu czas poświęcony na wdrażanie dużej liczby testów może się nigdy nie zwrócić. Nie ma większego sensu testowanie kodu trywialnego, który niewiele wnosi do logiki biznesowej. Również w sytuacjach, gdzie rozwiązanie problemu biznesowego nie jest wcale takie proste i oczywiste, zastosowanie TDD może nie być najlepszym rozwiązaniem. W takich sytuacjach lepsze może się okazać położenie nacisku na napisanie kodu poprawnie obsługującego wymaganą funkcjonalność. Obsługa błędów, przypadki graniczne itd. mogą mieć znaczenie drugorzędne. Test Driven Development ma także ograniczone zastosowanie w przypadkach, gdzie testy są żmudne, czasochłonne, a nie przynoszą znaczących korzyści dla całego projektu.

Porozmawiajmy!

    Wypełnij formularz,
    a my pomożemy Ci wdrożyć najnowsze rozwiązania!