poniedziałek, 30 września 2013

Kiedy pisać Unit Test?

TDD jest bardzo popularnym podejściem do pisania kodu. Najpierw piszesz test sprawdzający funkcjonalność, który nie przechodzi, później implementujesz ta funkcjonalność, aby ten test mógł przejść, a na końcu refaktorujesz kod i od nowa zaczynasz pisać kolejny test.

Dużo jest przeciwników TDD, gdyż uznaje się, że TDD jest zbyt wolny, nie nadaje się do małych zmian i nie ma czasu na 'ekperymentowanie' z TDD. Nie jestem w tym ekspertem, ale jedno wiem. Pisanie kodu produkcyjnego z TDD nie jest wolniejsze od samego pisania kodu, ale pisanie kodu eksperymentalnego z TDD jest wolniejsze od samego pisania kodu. Jest to najprostszy argument, przeciwko TDD.

Innym podejściem do pisania testów jest zasada Test-First. Kiedyś byłem, na praktyce w zagranicznej firmie, w której dwóch doświadczonych programistów pisało kod z takim podejściem. Jedna osoba pisała testy, a druga osoba implementowała te testy. Wszystko ok, ale bardzo często implementator kodu przychodził do twórcy testów, aby zmienić testy - w trakcie rozwoju aplikacji funkcjonalność się zmieniała jak i pomysły rozwiązania problemów. Test-First bardzo dobrze uzupełnia się z TDD, gdyż jedna osoba (na ogół jest to architekt) pisze podstawowe testy (kontrakty), a implementator kodu dodaje bardziej szczegółowe testy.

Ale, skoro TDD zawiera bardzo dużo czasu, a testy pisane metoda Test-First są często zmieniane to może pisać testy metoda Test-After? Minusem Test-After jest to, że bardzo trudno jest uzyskać wysokie pokrycie kodu. Mamy wtedy wewnętrzną potrzebę, aby zmienić coś w kodzie, aby łatwiej można było napisać test, nie mając przy tym gwarancji, że po zmianie wszystko będzie działało. Na dodatek nigdy nie ma czasu na testy i wszyscy mówią (managery), że po ważniejszych zmianach będzie można przetestować funkcjonalność. Oczywiście po tych zmianach nie mamy pewności czy wszystko działa tak jak wcześniej działało.

Może pisanie testów nie powinno być z góry określone, kiedy należy pisać. Może wystarczą testy, kiedy mamy taką potrzebę - Test-Whenever. Coś takiego jak zasada 80-20. 20% testów sprawdza 80% funkcjonalność. Niektóra funkcjonalność nie potrzebuje testów, a przy kodzie, gdzie mniej bezpieczniej się czujemy to możemy napisać więcej testów. I ta metoda ma swoją wadę. Zawsze jak zaczynam pisać nowy kod to mam wrażenie jakby wszystko było czytelne, oczywiste, proste i wszyscy powinni zrozumieć co kod robi, ale jak po roku wracam do swojego kodu to klnę na autora tego spaghetti kodu :)

Może testy nie powinny wyjść z potrzeby autora code, ale od osoby, która robi code review.

Dylematy z pisaniem testów jest bardzo dużo. Każda metoda ma swoich zwolenników i przeciwników. Może lepiej będzie zastosować metodę Test-Never?