Pizza, lody i diamenty – czyli jak wybrać strategię testowania
Testowanie jest jak pizza – jeden chce wegetariańską, drugi hawajską, a trzeci klnie na tego ananasa…
Nie ma uniwersalnej pizzy, która zasmakuje każdemu i dotyczy to nawet Margherity 😅
Tak samo jest z testowaniem – ile projektów, tyle różnych strategii testowania. Każdy projekt ma inne wymagania, priorytety i zasoby. Właśnie dlatego to, co sprawdzi się w jednym projekcie, niekoniecznie będzie dobrym rozwiązaniem w drugim.
Dobra, koniec tego pitu-pitu. Pokażę Ci, jakie strategie masz do wyboru, o co w nich chodzi i kiedy mogą się sprawdzić.
Piramida testów
Zaczynamy od klasyka, który dokładnie omówiłem w tym artykule – od piramidy testów, czyli od takiego Mercedesa w testerskim świecie. 😁
W dużym skrócie piramida testów składa się z kilku poziomów, które prezentują różny stopień szczegółowości testów:
Im wyżej jesteś, tym tych testów powinno być mniej i tym wyższy jest ich koszt utrzymania. To podejście, które ma na celu zmniejszenie kosztów i zwiększenie efektywności testowania poprzez skoncentrowanie się na niższych poziomach.
Piramida testów sprawdza się w projektach, gdzie priorytetem jest automatyzacja testów oraz szybkie wykrywanie błędów. W tym podejściu testy wykonują zarówno programiści (skupiając się na testach jednostkowych) jak i testerzy (skupiając się na wyższych poziomach).
Diament testowy
Gdy wpiszesz tę frazę w Google, to niekoniecznie dowiesz się, o co chodzi w tej strategii testowania… ale za to dowiesz się jak sprawdzić, czy diamenty są prawdziwe! 😆
Ale o co chodzi z tym diamentem?
Jest to pewna modyfikacja piramidy testów.
Diament testowy uwzględnia fakt, że projekt – a w związku z tym kod – jest czymś zmiennym i nie będzie cały czas wyglądał tak samo. W związku z tym część testów jednostkowych może na pewnym etapie okazać się bezużyteczna, bo na przykład jakieś moduły przestały istnieć.
Diament testowy adresuje ten problem i ogranicza ilość testów jednostkowych na rzecz testów integracyjnych, które zapewniają spójność między elementami systemu.
W tym podejściu NIE potrzebujemy 100% pokrycia kodu testami – programiści piszą testy jednostkowe wtedy, gdy rzeczywiście będą one istotne.
To podejście daje nam o wiele większą elastyczność niż klasyczna piramida testów. Dzięki elastyczności diamentu możemy szybko dostosować proporcje testów do bieżących potrzeb projektu. Wizualnie, diament testowy prezentuje się następująco:
Testowanie plastra miodu
Istnieje pewna firma, która tak jak ja, uwielbia miód. Spotify tak się polubił z tym produktem, że nawet zrobił z niego swoją strategię testowania.
Zauważono tam, że piramida testów kiepsko się sprawdza w świecie mikroserwisów. Największa złożoność w mikroserwisach nie tkwi w nich samych, ale w tym, jak ze sobą współdziałają i właśnie na tym warto skupić uwagę.
Strategia testowania plastra miodu, podobnie jak w przypadku diamentu testowego, skupia się na testach integracyjnych. Różni się jednak tym, że znacząco ograniczamy tu inne poziomy testów.
Graficznie można to przedstawić tak:
I wszystko byłoby spoko, gdyby nie to, że nazewnictwo w tym przypadku różni się od tego, które już znamy.
Testy Zintegrowane (to na samej górze plastra miodu) to coś w rodzaju testów E2E. Polegają one na testowaniu wielu systemów/usług naraz. Mimo że taki poziom tu występuje, to nie jest on zalecany ze względu na ryzyko niestabilności takich testów. A właśnie o stabilność nam chodzi.
Na samym dole mamy natomiast Testy Szczegółów Implementacji – to coś w rodzaju testów jednostkowych. Jeśli jakiś fragment kodu jest izolowany od reszty i posiada większą złożoność, to wtedy tworzymy dla niego dedykowane testy.
Puchar testowy
Skoro jesteś już na tym etapie, to należy Ci się puchar. 😁
I to nie byle jaki, bo jest to puchar testowy i wygląda tak:
Nie dość, że piękny, to na dodatek uwzględnia testowanie statyczne, które było pominięte we wszystkich wcześniejszych strategiach. Testy integracyjne wciąż są tu gwiazdą, ale w końcu mają porządny support.
Jeśli w Twoim zespole widzicie, że testowanie statyczne może przynieść Wam dużą wartość i chcielibyście je włączyć do swojej strategii – trofeum jest Wasze. 😉
Halo, policja! Chyba czegoś tu brakuje…
Brakuje nam… testów manualnych!
A przecież testowanie to nie tylko automatyzacja.
Wtedy wszyscy bylibyśmy deweloperami.
Istnieją dwie strategie, które uwzględniają testy manualne i koncentrują się na testach UI. Są też bardzo drogie.
Z drugiej strony są również bardzo cenne, bo to właśnie w tych strategiach skupiamy się na naśladowaniu użytkownika, do którego ma trafić oprogramowanie i te rodzaje testów dostarczają nam ogromną wartość biznesową.
Pierwsza z tych strategii to testowanie rożka lodowego i prezentuje się tak:
Jeśli usuniemy testy manualne, to mamy odwróconą piramidę testów, którą w tym przypadku nazywamy pizzą testową.
Nieco podobną strategią jest krab testowy. Kładziemy tu jednak większy nacisk na testy E2E i testy funkcjonalne. W tym podejściu zwracamy uwagę na to, jak aplikacja w ogóle prezentuje się wizualnie, czego zabrakło w poprzednich strategiach:
Jeśli nie mamy potrzeby przeprowadzania wielu testów integracyjnych w naszym projekcie, to obie te strategie mogą być dla nas lepszym wyborem niż te przedstawione wyżej. Mamy tu zupełnie inne priorytety.
To którą strategię wybrać?
Ta odpowiedź może Cię nie ucieszyć, ale… to zależy. 😁
Zanim wybierzesz strategię testów, musisz dokładnie zbadać, co właściwie testujesz i jaki jest cel tych testów.
Inaczej podejdziemy do testów małej, statycznej strony internetowej, a zupełnie inaczej do testów takich aplikacji jak Spotify czy Facebook.
Wiele zależy również od tego, ile masz czasu na testy, jak liczny jest zespół oraz jakie są wymagania. Strategie, które wymieniłem wyżej, nie obejmują testów wydajnościowych czy testów bezpieczeństwa, które dla niektórych aplikacji mogą być krytyczne.
Ważne, żeby pamiętać, że teoria to jedno, a praktyka to drugie. Testy mają przede wszystkim nam służyć i pomóc w wytwarzaniu wysokiej jakości oprogramowania, a nie komplikować życie. 😉
A jeśli o praktyce mowa, to podziel się w komentarzu, jakiej strategii Ty używasz i jak się ona sprawdza? Może kogoś zainspirujesz!
Mam wątpliwości co do tego czy testy jednostkowe byłyby zawsze najtańsze, bo przecież wymagają one też dobrego kodu.
Często pisze się kodzik tak, że nie da się go nawet jednostkowo testować, bo nie ma Dependency Inversion i… jest po prostu kiepsko.
Prawdę mówiąc im “droższy test” tym być może “tańszy kod”…
Tekst wyśmienity, jak zawsze. Idę czytać dalej!
Cześć Marcin,
dzięki za komentarz i przedstawienie szerszej perspektywy odnośnie testów jednostkowych. Wydaje mi się, że “to zależy” m.in.: od języka, czy ktoś stosuje TDD, jakie praktyki są w projekcie itd. Testy jednostkowe niektórym kojarzą się z prostymi testami, które możesz wygenerować jednym klikiem za pomocą Copilota, stąd może wynikać to uproszczenie co do kosztów samych testów jednostkowych.
Dzięki za miłe słowa 🥹