Testy jednostkowe to nie testy

Ten pomysł jest bardzo dziwny, ale za to śmiały – i to mi się podoba, dlatego dzielę się nim z Wami. To się zupełnie nie trzyma kupy, ale co tam, to nie pierwszy raz jak gadam głupoty, więc nie zamierzam się przejmować.


Według mnie, testy to taka rama wokół kodu. Najczęściej wygląda to tak, że piszesz testy żeby pokryć wartości zwracane i wywołania, piszesz kod i starasz się, żeby przeszedł testy jednostkowe. Wszystko dzieje się na poziomie jednostek, dlatego to testy "jednostkowe". Mockujemy zależności żeby było szybciej i żeby skupić się na jednostkach. Piszesz testy jako rusztowanie dla całego kodu.


Problem w tym, że Twój program to zbiór współzależnych jednostek, a testy jednostkowe nie testują programu jako całości. W fizyce to się nazywa emergencja – proste systemy wchodzące w interakcje z prostymi zasadami tworzą złożone systemy działające według innych zasad.


Na przykład atomy to całkiem zrozumiałe, samodzielne modele. Wpakuj trochę atomów do pudełka i nagle masz fizykę ciała stałego. Dodaj założenie, że elektrony nie mogą znajdować się wewnątrz protonów i już masz półprzewodniki. Dorzuć jeszcze kilka zasad i fizyka się poddaje, wywiesza białą flagę i przerzuca sprawę na chemię.


W kodzie też mamy do czynienia z emergencją. Większa liczba oddziałujących na siebie nawzajem jednostek sprawia, że twój program jest znacznie bardziej skomplikowany niż suma jego elementów. Nawet jeśli masz same grzeczne jednostki i każda ładnie przechodzi test, cała złożoność polega na ich integracji. Chodzi o to, żeby działał program, a nie poszczególne jednostki jego kodu. Skoro testy jednostkowe mówią tylko czy działa konkretny kawałek kodu, ale nie mówią, czy cały program zachowuje się poprawnie, to nie testują programu.

Ergo, to nie są testy.

To development.



Wiem, co sobie teraz myślisz, ale już na początku ostrzegałem, że to dziwaczny pomysł. Jestem odporny na krytykę. A jeśli mam być szczery, niezbyt mnie kręci wymyślanie mocnych argumentów żeby to potwierdzić. Bardziej ciekawi mnie, jakie mogą być konsekwencje takiego założenia. Jeśli możesz poudawać, że to wystarczy, to zobaczmy co się stanie, kiedy wreszcie to powiesz: Testy jednostkowe to nie testy!

Waterfall i Agile okazują się do siebie podobne. Wszyscy dookoła powtarzają: Agile rządzi, Waterfall jest beznadziejny. Ale kiedy się nad tym zastanowić, Waterfall to po prostu zorganizowane fazy pracy: projektowanie-rozwijanie-test-implementacja. W większości firm Agile to tylko Waterfall z bardzo krótkimi cyklami pracy. Zamiast kilku dużych cykli robią więcej małych i nazywają je iteracjami. (Jasne, pewnie są firmy, które pracują w Agile dużo lepiej, ale zignorujmy je tutaj, BO TAK).


Ale w Waterfallu testowanie to osobna faza, podczas gdy w Agile'u piszesz testy razem z kodem! W praktyce rzeczywiście piszesz testy jednostkowe w czasie rozwijania programu. Jeśli uznamy to za rozwój, a nie testowanie, wracamy do oddzielnych faz, a obie metodologie już nie zaprzeczają sobie nawzajem. Możemy znowu nauczyć się czegoś dzięki nim obu.


Możemy przestać kłócić się o to, kto pisze testy jednostkowe: programiści czy testerzy. Testy jednostkowe piszą programiści, bo to element programowania. Testerzy piszą inne testy.


Testowanie staje się dużo poważniejsze. Skoro testy jednostkowe to nie testy, nie można już spojrzeć na pokryty nimi kod i powiedzieć "Super, przetestowane". Więc jak powinniśmy testować? Okazuje się, że jest mnóstwo różnych metod, które ignorujemy myśląc, że testy jednostkowe załatwiają sprawę. Możesz zrobić snapshoty i porównywać je do mastera. Możesz budować oparte na regułach maszyny stanów. Możesz dopasować logikę do drzewa błędów. Testy nie są sprzężone z zestawem testów jednostkowych, więc możesz nadać priorytet dokładności, a nie szybkości działania. (Hej Hillel, a może byś wspomniał o metodach formalnych? Metody formalne są świetne, ale służą do projektowania systemów, a nie do ich testowania).


Jesteśmy zmuszeni traktować QA Inżynierów jako równych sobie. To znaczy, i tak zawsze powinniśmy ich tak traktować, ale przy założeniu "testy jednostkowe się nie liczą" to jeszcze bardziej oczywiste. Dobre testowanie jest naprawdę bardzo trudne, często trudniejsze niż cała ta logika biznesowa. Inżynierowie QA nie są obywatelami drugiej kategorii, są specjalistami.

Ten post nie zasługuje na lepsze zakończenie.
______________
Blog Hillela