TDD - okładka

O Test Driven Development

Opublikowano Kategorie Czysty kodCzas czytania 6min

W jednym z ostatnich wpisów na blogu poruszałem zagadnienia związane z testowaniem oprogramowania. Jednym z zagadnień, które pominąłem w tamtym artykule było podejście, Test Driven Development, w skrócie TDD. Do przykładów wykorzystałem bibliotekę Mocha oraz TypeScripta.

Geneza Test Driven Development

Myślę, że dobrym punktem startu będzie nakreślenie rysu historycznego. Wbrew pozorom sama idea TDD jest starsza, niż mogłoby się początkowo wydawać. Pierwsze wzmianki o technice noszącej znamiona TDD możemy znaleźć w bardzo starych książkach traktujący o programowaniu takich jak “Digital Computer Programming”1957 roku. Wzmiankę o czymś na wzór TDD możemy także znaleźć w raporcie z konferencji sponsorowanej przez Komitet Naukowy NATO1968 roku.

A software system can best be designed if the testing is interlaced with the designing instead of being used after the design.

Niemniej jednak wtedy nie nosiło to miana Test Driven Development. Termin TDD został spopularyzowany przez 2 książki autorstwa Kenta Becka:

Obecnie termin ten jest tak popularny, że natknąłem się w sieci nawet na kursy, warsztaty i szkolenia skupiające się na temacie TDD. Co ciekawe, niektóre z nich potrafią kosztować naprawdę spore pieniądze.

Czym jest TDD?

Opowiadanie o historii TDD bez wytłumaczenia, na czym ono polega, byłoby niewybaczalnym faux-pas z mojej strony, także szybko naprawiam ten błąd. W skrócie Test Driven Development jest to technika wytwarzania oprogramowania, w której najpierw tworzymy test. Dopiero potem tworzy się kod sprawiający, że test przejdzie pomyślnie. Procedura wytwarzania kodu metodą TDD składa się z trzech etapów — red, green oraz refactor.

Test Driven Development -Red green refactor diagram

 

Red — na samym początku tworzony jest test. Na przykład dla kalkulatora mógłby to być test dodawania. Rzeczą oczywistą jest, że uruchomienie takiego testu da wynik negatywny. W końcu test sprawdza nieistniejący kod. Dla wspomnianego kalkulatora test mógłby wyglądać następująco.


import { expect } from 'chai';

import SimpleCalculator from '../src/SimpleCalculator';

describe( 'SimpleCalculator - Unit tests' () => {
  let calculator: SimpleCalculator;

  before( () => {
    calculator = new SimpleCalculator();
  } );

  describe( 'add()', () => {
    it( 'should add two numbers and return a correct result', () => {
      expect( calculator.add( 2, 2 ) ).to.eql( 4 );
    } );
  } );
} );

Green — w tej fazie do istniejącego testu wytwarzany kod, który sprawi, że test przejdzie pomyślnie.


export default class SimpleCalculator {
  public add( a: number, b: number ): number {
    return a + b;
  }
}

Jak możesz zauważyć, brakuje tutaj innych metod, których można by się spodziewać w kalkulatorze. Jest to zabieg celowy. Istotne jest to, aby NIE pisać kodu, którego użyteczność wykracza poza wcześniej napisany test. W tej fazie nie jest istotna wydajność ani elegancja kodu. Jedynym jego zadaniem jest sprawienie, aby test przeszedł pomyślnie.

Refactor — faza refaktoryzacji. W tej fazie można zoptymalizować i usprawnić wcześniej wspomniany kod. Wciąż nie należy zapominać o wcześniej wspomnianej zasadzie — nie należy wykraczać poza to, co obejmuje test. Kod z przykładu jest na tyle prosty, że fazę refactor w tym przypadku można pominąć. Po ukończeniu cyklu możemy rozpocząć kolejną iterację poprzez napisanie testu na przykład dla odejmowania. Cykl ten powinien być powtarzany tak długo, aż uzyskamy finalną aplikację.

Zalety i wady TDD

Niewątpliwą zaletą TDD jest możliwość wczesnej detekcji i eliminacji błędów. Oprócz tego mając już zestaw testów, które przeszły przez 3 fazy, zwiększa się odporność systemu na regresję. Jeżeli w fazie green uruchomiony kod spowoduje porażkę innego testu, to jest to oczywisty dowód na powstanie regresji w kodzie.

Kolejnym benefitem jest to, że zgodnie z TDD każda linijka kodu, który został dodany, jest przetestowana, co daje pokrycie kodu na poziomie 100%. Oczywiście do sprawdzenia pokrycia kodu możemy użyć narzędzi tj. Istanbul, ale TDD również nam to zapewnia. Warto pamiętać, że dla biznesu 100% code coverage może być ważnym czynnikiem, a niekiedy kartą przetargową przy pozyskiwaniu klientów. To, czy ma to sens, to już inna para kaloszy 😉

Korzystanie z TDD zwiększa świadomość programisty, nad tym co tworzy oraz jak działa projektowany system. Zaczynanie programowania od testów daje szerszą perspektywę nie tylko na wartość biznesową, którą ma dawać tworzony kod, ale też na architekturę projektowanego systemu.

TDD pozwala również skupić się na jakości i użyteczności publicznego interfejsu tworzonego kodu. Zaczynając od testów, programista musi przemyśleć, jak powinien wyglądać interfejs kodu docelowego.

Jeśli chodzi o wady TDD, to dla początkujących pisanie testu do nieistniejącego kodu, może stanowić wyzwanie. Niemniej jednak po kilku napisanych testach w podejściu TDD nie powinno to stanowić większego problemu. Trudne może okazać się ciągłe pamiętanie, żeby nie dopisywać więcej kodu, niż jest to potrzebne. Pracując w podjeściu TDD, sam bardzo często się na tym łapałem.

Warto też pamiętać, że TDD to nie jest jedyna słuszna droga, tylko narzędzie mające pomóc programiście. Jeżeli czujesz, że TDD nie jest dla Ciebie, to nie jest to nic złego. Nie ma co się zmuszać, nic na siłę.

Podsumowanie

Bardzo jestem ciekaw czy miałeś/aś już styczność z TDD, a jeśli tak to, co o nim sądzisz. Zachęcam do pozostawienia komentarza. Sam osobiście nie programuję zbyt często w podejściu TDD, jednak w trakcie pisania tego artykułu uznałem, że być może warto to zmienić! Jak zwykle zachęcam też do zapoznania się z materiałami dodatkowymi i źródłami.

Źródła i materiały dodatkowe

Dominik Szczepaniak

Zawodowo Senior Software Engineer w CKSource. Prywatnie bloger, fan włoskiej kuchni, miłośnik jazdy na rowerze i treningu siłowego.

Inne wpisy, które mogą Cię zainteresować

Zapisz się na mailing i odbierz e-booka

Zapisując się na mój mailing, otrzymasz darmowy egzemplarz e-booka 106 Pytań Rekrutacyjnych Junior JavaScript Developer! Będziesz też otrzymywać wartościowe treści i powiadomienia o nowych wpisach na skrzynkę e-mail.

Subscribe
Powiadom o
guest

0 komentarzy
Inline Feedbacks
View all comments