Jeśli chcemy być w pełni szczerzy, to gruntowne testowanie małych aplikacji było zawsze możliwe, ale zazwyczaj kompletnie nieopłacalne. Przy zmieniających się okolicznościach możemy jednak powiedzieć, że coś, co do tej pory nie było ani osiągalne czasowo, ani finansowo, powoli staje się możliwe.
Druga z zasad testowania z sylabusa ISTQB® Poziomu Podstawowego mówi: Testowanie gruntowne jest niemożliwe. Testowanie wszystkiego jest niewykonalne, z wyjątkiem trywialnych przypadków. Samo stwierdzenie jest dość mocne, więc zacznijmy od przyjrzenia się jego fundamentom.
Eksperyment trywialny
Załóżmy testy oprogramowania, którego głównym elementem jest pole ograniczone do 10 znaków, do którego można wprowadzać jedynie znaki z alfabetu łacińskiego (składającego się z 26 znaków). Załóżmy także, że wszystkie pozostałe znaki są zablokowane.
Do przeprowadzenia testów poprawności tego pola potrzebujemy jednego testu, ale jednocześnie olbrzymiej ilości danych testowych. Około 141 bilionów danych. Jeśli każdy test trwałby 1 sekundę, to uruchomienie pełnego test runu zajęłoby 4 476 lat. Jeśli za godzinę pracy testera mielibyśmy zapłacić 50 zł, to sumaryczny koszt przeprowadzenia testów wyniósłby prawie 2 miliardy złotych.
Mówimy więc o bardzo dużych liczbach – bardzo długim czasie i olbrzymich kosztach. W takim kontekście i przy wiedzy o tym, że mówimy, że testujemy trywialną funkcjonalność, to stwierdzenie, że testowanie gruntowne jest niemożliwe, jest w pełni uzasadnione.
Jednak zrobiliśmy bardzo dużo założeń, m.in. takie, że testowanie będzie wykonywane ręcznie. Zróbmy jednak inne założenia:
- Oprogramowanie będzie testowane automatycznie – jednym testem z wieloma danymi.
- Nie będziemy testowali na poziomie interfejsu graficznego, ale poniżej - na warstwie integracji, a może na poziomie kodu.
- Czas wykonania testu zejdzie do 1 ms.
- Koszt wykonania testu na jednej maszynie to przede wszystkim zużycie energii sięgające 0,25 kWh, czyli około 25 gr za godzinę.
Ile teraz potrwają testy i ile będą kosztować? Potrwają około 4,5 roku i będą kosztować około 10 tysięcy za energię i pewnie około 5 tysięcy za sprzęt komputerowy, łącznie około 15 tysięcy złotych. Liczby stają się dla nas coraz bardziej „osiągalne”. Gdybyśmy chcieli zwiększyć liczbę komputerów, to cena wzrośnie, ale za to czas wykonania będzie spadał z każdą kolejną maszyną. Przy 9 czas spadnie do pół roku testów. Dochodzimy więc do miejsca, w którym zarówno na poziomie czasowym jak i biznesowym testowanie gruntowne byłoby możliwe.
Eksperyment mniej trywialny
Choć ciągle tkwimy w dość trywialnym przykładzie, to jednak zaczynamy widzieć możliwość wykonania testów. Jednak dokładając dodatkowe składowe do złożoności oprogramowania, np. konstruując formularz z większą liczbą pól, to czas wykonania nie rośnie z kwadratem, ponieważ pola rzadko kiedy są ze sobą powiązane. Dodatkowo konstruując formularz tak, by ograniczać użytkownikowi możliwość dokonania wyboru, coraz bardziej limitujemy liczbę testów do przeprowadzenia.
Spójrzmy na popularną wyszukiwarkę lotów, która stanowi całościową funkcję oprogramowania.
Chociaż większość z pól stwarza pozór pola tekstowego, jest tak naprawdę listą wyboru. Wpisywanie znaków lotniska „z:” zwróci nam listę lotnisk z danymi znakami. To samo z „do:”. Lotnisk rejsowych jest około 4000 na całym świecie.
„Wylot” i „Powrót” to listy z kalendarzem. Wyboru można dokonać na 365 dni do przodu.
Podróżni to listy „dorosłych” i „dzieci” do 8 elementów.
Pola są ze sobą powiązane w pewnym zakresie, np. „wylot” nie może być późniejszy niż „powrót”, ale te powiązania nie są bardzo silne.
Ile czasu potrzeba i jakie są koszty testów?
- kombinacje wszystkich lotnisk to 16 milionów,
- kalendarze („Wylot” i „Powrót”) to około 66 600 kombinacji,
- podróżni (Dorośli i Dzieci) to 81 kombinacji.
Jeśli przemnożymy przez siebie wszystkie kombinacje osiągniemy 86 bilionów danych testowych. Jeśli wrócimy do założenia, że jeden test trwa 1 ms, okaże się, że potrzebujemy 2737 lat na testy. Patrząc jednak na powiązania między polami, to możemy uznać, że lotniska nie wpływają na daty, a te na podróżnych. W związku z tym wystarczy wykonać testy jedynie dla tych powiązań pól, które wymagają największej liczby testów, w tym przypadku lotnisk – 16 000 000. W tej puli zawrą się już testy dla dat i pasażerów. Przy założeniach z poprzedniego przykładu okazuje się, że pełne testy zajmą 4 godziny, 26 minut i 40 sekund oraz będą kosztować 1111 złotych.
To prowadzi do wniosku, że testowanie staje się coraz bardziej skończone i to, co wydawało się niemożliwe, staje się możliwe.
Podsumowanie
Czego nie uwzględniliśmy w naszym eksperymencie logicznym? Wielu rzeczy.
Przykładowo pominęliśmy testy charakterystyk takich, jak niezawodność czy wydajność. Testy te jednak są policzalne i są również skończone więc zwiększą koszty oraz wydłużą czas testów funkcjonalnych. Nie uwzględniliśmy mnogości środowisk, które szczególnie dla aplikacji mobilnych dążą do milionów kombinacji (OS / hardware / rozdzielczość wyświetlacza etc.). Jednak 90% użytkowników będzie korzystała z około 100 kombinacji sprzętowo-software’owych i daje nam to szansę na limitowanie kosztów testów. Przy okazji skończonych testów producenci mogą publikować listę sprzętów i wersji systemów operacyjnych, jakie te wspierają (na jakich testowali) i dawać gwarancję, że na nich takie wyszukiwanie działa.
Równocześnie warto pamiętać, że w wyliczeniach nie zrobiliśmy założeń na rosnącą świadomość projektową co do konstrukcji oprogramowania (w tym zależności) co doprowadziło nas do zastosowania tylko niewielkiej części mechanizmów optymalizacji. Nie uwzględniliśmy siły wartości inteligencji. Tej ludzkiej, która potrafi wskazać gdzie testy mają uzasadnienie i miejsc, w których nie mają one żadnego przełożenia na zwiększenie pokrycia oraz tej sztucznej (AI) do wsparcia prowadzenia testów. Skoncentrowaliśmy się na brute force’owym wykonaniu wszystkich testów w poszukiwaniu nawet najbardziej trywialnych testów.
Automatyzacja zamiast pracy ręcznej, kilka realnych założeń i jedna z podstawowych zasad testowania może zostać obalona. Wraz z nią jak domek z kart rozsypuje się pełen zestaw siedmiu zasad. Skoro gruntowne testowanie jest możliwe, to oznacza to, że możemy znaleźć wszystkie defekty i/lub udowodnić ich brak (zasada 1); testy się nie zużyją, jeśli są wszystkimi testami do pokrycia funkcjonalności (zasada 5); testowanie nie będzie zależało od kontekstu, jeśli naszym założeniem zawsze będzie przetestowanie wszystkiego (zasada 6).
Aneks
To, czy oprogramowanie jest możliwe do gruntownego przetestowania, czy też nie będzie zależało od tego, jak zostało skonstruowane. Na poziomie jego projektowania możemy już ustalić pewne zasady, które spowodują, że produkt będzie miał mniej opcji, mniejszą elastyczność wyboru czy wspierał mniej środowisk. To ograniczy nam liczbę kombinacji zdarzeń w oprogramowaniu i testów oraz danych testowych do zaprojektowania i wykonania.
Użyj tych heurystyk:
- Buduj aplikacje z dobrym UX-em dla szerokiej grupy odbiorców, co zazwyczaj oznacza: buduj proste formularze i procesy.
- Buduj aplikacje dopasowane pod konkretne grupy odbiorców i na konkretne rynki. Mając większą świadomość środowisk końcowych odbiorców i preferowanych funkcji limitujesz liczbę scenariuszy do przetestowania.
- Budując proste aplikacje ograniczasz ryzyko problemów wydajności czy niezawodności.
- Ogranicz do minimum dane wrażliwe jakie przetwarzasz lub przechowujesz. Ograniczy to zakres testów bezpieczeństwa do przeprowadzenia.
- Użyj powszechnych i popularnych technologii. Mniejsza szansa na defekty pochodzące ze środowiska programistycznego i łatwiejsze utrzymanie produktu.
W takim kontekście twoje oprogramowanie będzie po prostu łatwiejsze w testowaniu, a w wysiłkach testowych możesz zbliżać się do uzyskania 100% całościowego przetestowania.
Redakcja testerzy.pl