Mój drugi artykuł dla serwisu PasjaOnline wprowadza czytelników w świat testowania automatycznego. Serdecznie zapraszam do lektury: czym są testy automatyczne http://pasjaonline.pl/testy-automatyczne/.
Automatyzacja testów to ostatnimi czasy dość modny temat. I nie bez przyczyny. Automatyzowanie powtarzalnych czynności jest w końcu sporym ułatwieniem pracy. W miarę rozrastania się ilości przypadków testowych, ich konsekwentne wykonywanie staje się coraz trudniejsze. Same testy, spisane w formie tekstowej, zaczynają być ciężkie w utrzymywaniu. Po co dziesiąty raz klikać tą samą ścieżkę, skoro można napisać program, który zrobi to za nas?
Oczywiście automatyzacja nie jest lekiem na całe zło. Pociąga za sobą kolejne problemy, takie jak konieczność tworzenia i aktualizowania testów automatycznych oraz utrzymywania środowisk, gdzie testy mogłyby być wykonywane.
Stosowanie testów (zwłaszcza jednostkowych w podejściu TDD – czyli najpierw piszemy testy, potem kod) w znaczący sposób wpływa także na podejście do pisania kodu, wymuszając stosowanie dobrych praktyk. Najlepiej testuje się klasy o wysokiej spójności (czyli: jedna klasa odpowiada za jedną funkcjonalność) i małym sprzężeniu (czyli zależności od innych klas).
W dużych projektach automatyzacja testów bywa jednak nieunikniona, zwłaszcza jeśli testy zostają zaprzęgnięte do środowisk ciągłej integracji. W takich środowiskach Continuous Integration, gdzie po każdej zmianie kodu budowana jest aplikacja i uruchamiane wszystkie testy automatyczne. Oczywiście taki proces może trwać całkiem sporo – o ile nie zastosowano np. takich technik jak zrównoleglenie testów (np. za pośrednictwem narzędzia Selenium Grid).
Testy automatyczne – podział
Same testy automatyczne w literaturze dzieli się na kilka warstw, w uproszczeniu:
- testy systemowe – obejmujące całe środowisko, testy funkcjonalne (czyli testy funkcjonalności) i niefunkcjonalne (testy bezpieczeństwa, obciążeniowe, wydajnościowe itd.)
- testy integracyjne – nacisk położony jest na współdziałanie rozłącznych fragmentów systemu
- testy jednostkowe – testowanie wyizolowanych fragmentów, na najniższym poziomie.
Osiągnięcie wyizolowanych fragmentów systemu nie zawsze jest sprawą prostą. Jest tak zwłaszcza w przypadku próby stworzenia zestawu testów jednostkowych do już istniejącego kodu. Może się okazać, że bez totalnej refaktoryzacji kodu jest to niemożliwe (np. ze względu na wysoki stopień sprzężenia klas). Jeżeli jednak klasy są zachowują dużą modułowość, ewentualne zależności pomiędzy nimi można zastąpić poprzez stosowanie klas-zaślepek, „mockowanie” i tym podobne techniki.
Jakie testy automatyczne powinny zostać napisane i w jakiej ilości
Podczas planowania testów automatycznych pojawia się pytanie, ile powinno być testów jednostkowych, a ile testów wyższych stopni? Najprościej oszacować to, opierając się na piramidzie testów. W sieci znajdziecie wiele rodzajów tego typu piramid – podział testów nie jest jednoznaczny. Nie przejmujmy się jednak sztywnymi klasyfikacjami, przejdźmy do konkretów – istota rzeczy jest bardzo prosta.
U podstawy piramidy umieszczone zostały testy jednostkowe. Tych powinno być najwięcej. Działają na klasach i funkcjach, są więc najszybsze i najłatwiejsze w utrzymaniu. Powinna spoczywać na nich odpowiedzialność sprawdzania np.:
- warunków brzegowych,
- klas równoważności (pisałam w poprzednim artykule),
- przypadków negatywnych i pozytywnych,
- wszelakich walidacji danych wejściowych (puste stringi, nulle, znaki specjalne itd).
Nieco wyżej – testy działające na wyższej warstwie, więc testy integracyjne, działające na stykach dwóch elementów systemu. W zależności od testowanego systemu mogą wyglądać zupełnie inaczej. Inna będzie specyfika testów systemów elektronicznych dostarczających dane do modułu bazodanowego, inna prostej strony www. Tu za testy integracyjne można przyjąć np. testy sprawdzające, czy na danej stronie wyświetlają się żądane elementy.
Testy typu end-to-end są (czasem nie do końca poprawnie) zwane testami akceptacyjnymi. Syllabus ISTQB testy akceptacyjne definiuje na „warstwie” biznesowej, a więc na jednej z wyższych warstw. End-to-end są najtrudniejsze w utrzymaniu, zależne od wielu elementów (np. modułu dostarczającego dane do aplikacji itd.). Są przez to mniej niezawodne niż testy niższych poziomów. Powinno być ich najmniej – mogą pokrywać kilka najważniejszych ścieżek w aplikacji.
Warto także pamiętać o testach niefunkcjonalnych, zwłaszcza obciążeniowych i wydajnościowych. Mogą być one również automatyzowane i dzielone na mniejsze moduły.
Źródła:
- Syllabus ISTQB, poziom podstawowy