piątek, 7 września 2012

ile testów jednostkowych warto napisać?

a na co mnie to?

Testy jednostkowe (jak i wszelkie pozostałe) przydają się. Co prawda nie są, jak sądzą niektórzy, gwarancją tego, że nasz kod nie posiada błędów i jest wolny od jakichkolwiek pomyłek. Dają nam jedynie informacje, że nie udało się danego błędu znaleźć oraz, co równie ważne, że w określonych przypadkach kod/aplikacja zachowuje się tak, jak zakładamy.

Ta druga informacja jest w stanie ułatwić nam życie w naprawdę wielkim stopniu, gdy dochodzimy do momentu, gdy kod trzeba refaktoryzować/modyfikować. Testy dają nam pewność, że w danych przypadkach, po wszystkich wprowadzonych zmianach, wszystko nadal działa w sposób prawidłowy.

kiedy pisać testy jednostkowe?

Wiele osób uważa, że pełen zestaw testów jednostkowych powinien powstać przed implementacją kodu. Osobiście nie zgadzam się z tym stwierdzeniem.
Nie oznacza to jednak, że jestem zdania, że najpierw powinien powstać kod, a później testy do niego. To jest poważny błąd. Z doświadczenia wiem, że gdy już mamy wszystko zrobione, to testy zostaną odłożone na bliżej (zazwyczaj dalej:) nieokreśloną przyszłość lub zostaną napisane po łebkach.

Ja zazwyczaj piszę jeden test, a następnie implementuję kod, który go przejdzie i tak do momentu, gdy mam już całą funkcjonalność gotową.
Na przykład implementując metodę do dzielenia division(dividend, divisor) kolejne kroki wyglądały by tak:
  • test, który sprawdza, czy dostanę wyjątek, gdy dzielnik jest równy zero
  • implementacja kodu, który wyrzuca odpowiedni wyjątek
  • testy sprawdzające czy wynik dzielenia jest poprawny
  • implementacja dzielenia
Oczywiście w przypadku rzeczywistego kodu pojedyncze metody mogą posiadać dużo bogatszy zestaw testów.
Po pełnej implementacji metody warto się jeszcze na chwilę nad nią zatrzymać i zastanowić się, czy nie da się czegoś jeszcze napisać lepiej/ładniej, bo przy bardziej skomplikowanych zdarza się, że jest jeszcze trochę miejsca na dalsze ulepszenia. Przy okazji mogą również wpaść do głowy pomysły na kolejne testy:)

czy wszystko warto testować?

Może się komuś narażę tym stwierdzeniem, ale osobiście uważam, że nie wszystkie metody są warte testowania np. takie gettery i settery (nie wdając się w polemikę, czy powinno się ich używać, czy nie, bo fakt jest taki, że istnieją:), które nie mają żadnej dodatkowej funkcjonalności poza ustawieniem/odczytaniem wartości atrybutu. Są to metody, których testowanie, moim zdaniem, jest jedynie stratą czasu. Przeglądając kody pewnie natknąłbym się na kilka innych przypadków, ale to jest moim zdaniem najistotniejszy przykład.
Jednak poza tego typu trywialnymi metodami, to wydaję mi się, że należy (a przede wszystkim - warto) testować wszystko.

ile testów?

Stwierdzenie "im więcej, tym lepiej" wcale się w tym przypadku nie sprawdza. Pisać testy należy mądrze i przede wszystkim trzeba zwracać uwagę, aby się nie powtarzać. Nie ma najmniejszej potrzeby testować dziesięć razy to samo, w ten sam sposób. Takie działanie jedynie zaciemni kod, a przez to trudniej się będzie w testach odnaleźć. Dodatkowo stwarza iluzoryczne pojęcie dobrze przetestowanego kodu.

na koniec słów kilka o tym, kiedy koniec

Można założyć z dużą dozą prawdopodobieństwa, że całego kodu w aplikacji nigdy nie uda się w pełni przetestować. Raz dlatego, że możemy (ani nikt z naszego zespołu) na pewne przypadki po prostu nie wpaść, a dwa dlatego, że pełne testowanie niektórych funkcjonalności jest zbyt czasochłonne i niekiedy świadomie decydujemy się na przetestowanie jedynie najważniejszych (i najprawdopodobniejszych) przypadków zastosowania. Na pozostałe poświęcamy czas jedynie, gdy klient zgłosi jakieś zastrzeżenia.