Bug Test Driven Development

Bug Test Driven Development

To uczucie, gdy kończymy feature, przeklikujemy ostatni raz aplikację, zatrzymujemy się na chwilę, aby nacieszyć się zakończoną pracą, a tu bach! W innej części aplikacji zauważamy bug’a. Co więcej, kojarzymy ten problem, bo już go poprawialiśmy. Pierwsza myśl? Ktoś (bo przecież nie my) znowu to zepsuł!

Nie ma chyba nic bardziej frustrującego niż konieczność wykonania dwa raz tej sam pracy. Jeżeli to dopiero drugi raz to jeszcze nie jest najgorzej. Miałem styczność z projektem, gdzie występował dość złożony kawałek aplikacji. Jedna zmiana w tym obszarze praktycznie zawsze powodowała powrót jednego lub więcej bugów z przeszłości. Frustrująca praca zaczęła się ciągnąć tygodniami.

Im bardziej skomplikowana aplikacja i dłużej rozwijana tym ciężej jest ogarnąć co się dzieje pod spodem. Nie mówiąc już o nowych osobach, które mogą pojawić się w projekcie. Skąd Ci ludzie mają wiedzieć o wszystkich rzeczach, na które wpływa, bądź od których jest zależny dany kawałek kodu? Ok, im kod lepiej utrzymany, mam na myśli jego SOLIDność, tym łatwiej jest się w nim odnaleźć. Jednak nie zmienia to faktu, że coś możemy przeoczyć. W językach statycznie typowanych jest ciężej, jednak wkraczając w świat JS’a, szanse na przeoczenie czegoś rosną wykładniczo.

Jak upewnić się, że pokonaliśmy buga raz na zawsze?

Nikt z nas nie chce przecież w kółko wykonywać tej samej pracy. Nie na tym polega rozwój software’u. Kluczem tutaj są zautomatyzowane testy. W rzeczywistości bywa z nimi różnie. Idealnie byłoby mieć pokryty kod w 90% lub więcej, zazwyczaj niestety nie wygląda to tak kolorowo. Albo testów nie ma wcale albo są takie testujące tylko jeden scenariusz albo ktoś kiedyś zaczął je pisać, ale potem terminy zaczęły gonić i testy poszły w zapomnienie.

Bug Test Driven Development*

Tak, czy inaczej warto trzymać się jeden zasady – pojawił się bug? To piszemy na niego test. Pokrywając problem testem mamy pewność, że ktoś, zapewne nieumyślnie, znowu go nie spowoduje. Żeby być bardziej precyzyjnym – błąd spowodować może, ale zapali mu się czerwona lampka i będzie wiedział, że coś zepsuł przy okazji swojej pracy.

Test stanowi również pewien rodzaj dokumentacji problemu. Najpierw udowadnia, że bug faktycznie występuje w kodzie. Następnie przedstawia scenariusz w jakim problem miał miejsce. Ostatecznie, gdy dokonamy poprawek w kodzie, daje nam pewność, że problem został wyeliminowany raz na zawsze.

Jeżeli już poświęcimy czas na żmudne debugowanie i naprawienie problemu warto zostawić po sobie taki ślad. Całkiem możliwe, że w przyszłości ktoś nie będzie musiał drugi raz wykonywać całej tej pracy ponownie.

Sposób na wprowadzenie testów do projektu

Jeżeli ktoś jest w sytuacji, gdzie nie ma prowadzonych żadnych testów i/lub brak w zespole umiejętności, czy kultury ich pisania, pokrywanie występujących błędów testami jest zawsze jakimś sposobem na wprowadzenie testów do projektu. Nie jest to idealne podejście, ale lepsze takie niż żadne.

Często również w prostych aplikacjach CRUD, gdzie mamy prostą architekturę typu: baza danych -> repozytorium -> serwis -> controller, a większość logiki biznesowej to przepisywanie modelu na data contract i na odwrót, możemy się zniechęcić do pisania testów od podstaw (mam na myśli testy do napisanego już kodu, nie podejście TDD, które odwraca całkowicie koncepcje tworzenia aplikacji).

Dlaczego może tak się zdarzyć?

Może dość kontrowersyjne stwierdzenie, ale można odnieść wrażenie na pierwszy rzut okna, że testy do takiego kodu za wiele nie wnoszą. Jest to w pewnym stopniu uzasadnione, bo prawdziwa wartość tych testów może ukazać się dopiero po czasie. Podczas dalszego rozwoju aplikacji, czy wdrażaniu nowego programisty. Możemy w takiej sytuacji spróbować zacząć wprowadzać testy do projektu pokrywając nimi występujące bugi.

Dlaczego łatwiej będzie zacząć pisać testy pokrywające bugi?

Między innymi dlatego, że w przypadku poprawiania bug’a od razu widzimy wartość tego testu. Dodając półżartem – może te same błędy pojawiające się kolejny raz bolą bardziej niż nowe?:) A tak bardziej na poważnie – lepiej zacząć późno niż wcale i traktować to jako drogę do wejścia w nawyk pisania testów.

Na zakończenie

Przytoczone tutaj zalety pokrywania błędów testami tyczą się oczywiście ogólnie testów, nie tylko tych pisanych na potrzeby konkretnego bug’a. Czemu więc zdarza się pisać aplikacje niepokryte testami? Pierwsze dwie rzeczy jakie przychodzą mi do głowy to lenistwo i brak świadomości jakie tak naprawdę pociąga to za sobą (początkowo ukryte) koszty. Może pokrywanie chociaż błędów testami to jakiś sposób na szybsze przekonanie się o prawdziwej ich wartości?

*Nazwa oczywiście wymyślona na poczekaniu, nie znalazłem żadnego terminu wśród tych najpopularniejszych typu TDD, który opisywałby to podejście. Najbliżej pasujący (chodź nie do końca), istniejący termin to testy regresyjne.

Powiązane

books#11 – Wasze propozycje! Jak zapewne zauważyliście, nasz konkurs (dostępny TUTAJ) dobiegł końca. Musimy przyznać, że długo zastanawialiśmy się nad jego formą. Pytanie brzm...
Narzędzia które powinien znać każdy web developer... Oprócz głównego IDE, z którego korzystamy każdego dnia istnieje masa pobocznych narzędzi, które pomagają nam w przeróżnych zadaniach. Dzisiaj prez...
Getting started on ASP.NET Core & React ̵... Contents Episode 1 - Introduction Episode 2 - Backend / Infrastructure Episode 3 - Frontend Setup Episode 4 - Data flow Episode 5 -...
Must have dla każdego .Netowca – Application... Parę tygodni temu Microsoft przedstawił wersje robocze "Application Architecture Guidance", czyli poradników dotyczących architektury aplikacji bu...