JMeter – czyli narzędzie do testowania wydajności aplikacji – może również być użyty w testach funkcjonalnych. Mogą wystąpic sytuacje, kiedy będziesz chciał(a) napisać test który przetestuje czy Twoje API zwraca to co powinno. Dobrymi przykładami są testy sprawdzające wynik odpowiedzi, status kodu czy też cała sekwencja zdarzeń.
Na zawsze ponosisz odpowiedzialność za to, co oswoiłeś.
Cześć 🙂
Dzisiejszy artykuł jest kontynuacją serii o narzędziu JMeter i testowaniu. Pierwszy artykuł – teoretyczny – był o podstawach testów wydajnościowych, a w ostatnim opisywałem podstawowe funkcje JMetera – tak aby móc odpalić pierwsze testy.
W dzisiejszym artykule napiszemy kilka scenariuszy do publicznego API do testów, dziś dowiesz się
- Co można sprawdzać przy pomocy JMetera
- Jak sprawdzanie wyników wpływa na wydajność testów
- Testujemy sprawdzenie odpowiedzi API
- Przetestujmy ograniczenie
Co można sprawdzać przy pomocy JMetera
JMeter udostępnia kilka ciekawych asercji. Jednak z punktu widzenia typowego developera – głównie korzysta się ze znacznie zawężonego grona asercji (response, duration, size).
- Response Assertion – używana najczęściej. Pozwala na sprawdzenie między innymi odpowiedzi wiadomości, zwracane kody, nagłówki.
- Duration Assertion –prosta i przydatna asercja, szczególnie w testach wydajnościowych. Weryfikuje czy dany test zakończył się w zadanym czasie. Jeżeli wprowadzony czas zostanie przekroczony asercja zwróci błąd.
- Size assertion – sprawdza wielkość odpowiedzi czy jest zgodna z oczekiwaną (mniejsza/większa/równa/różna). Możemy sprawdzić zarówno całą odpowiedź jak też poszczególne komponenty, np. tylko headery czy też ciało odpowiedzi. Wartość jest definiowana w bajtach!
- XML Assertion – waliduje czy odpowiedź posiada poprawnie sformatowany dokument XML. Jest to walidacja poprawności dokumentu tylko pod kątem poprawności tagów XML itp. Walidacja nie obejmuje schemy, DTD czy też innych walidacji!
- HTML Assertion – sprawdza poprawność zwróconego pliku HTML.
Jak sprawdzanie wyników wpływa na wydajność testów
Pomimo iż sprawdzanie każdej zwróconej odpowiedzi może być kuszące należy pamiętać, że każda asercja ma swój koszt w postaci dodatkowego obciążenia CPU czy też pamięci. Jeżeli masz zamiar wykonywać testy wydajnościowe to zastanów się wcześniej czy aby na 100% potrzebujesz sprawdzać konkretną rzecz! Jeżeli tak – to ogranicz sprawdzanie odpowiedzi tylko do najważniejszych!
Assertion | CPU/Memory Usage |
---|---|
Response Assertion | Średnie |
Duration Assertion | Niskie |
Size Assertion | Niskie |
XML Assertion | Wysokie |
Beanshell Assertion | Zmienne (zależne od skryptu) |
MD5Hex Assertion | Niskie |
HTML Assertion | Wysokie |
XPath Assertion | Wysokie |
XML Schema Assertion | Wysokie |
JSR223 Assertion | Zmienne (zależne od skryptu) |
Compare Assertion | Wysokie |
SMIME Assertion | Średnie |
Json Assertion | Wysokie |
Tabelka pochodzi z tego wpisu. Do którego zresztą zachęcam jeżeli chcesz więcej szczegółów o asercjach w JMeter.
Testujemy sprawdzenie odpowiedzi API
Zacznijmy od czegoś prostego. Chcemy zweryfikować że dostęp do naszego API faktycznie wymaga uwierzytelnienia. Będziemy próbowali wywołać jeden z endpointów (gorest.co.in//public-api/users) bez użycia authorization tokenu.
Przy normalnym strzale bez użycia autoryzacji dostajemy taki komunikat:
1 2 3 4 5 6 7 8 9 10 11 12 13 | { "_meta": { "success": false, "code": 401, "message": "Authentication failed." }, "result": { "name": "Unauthorized", "message": "Your request was made with invalid credentials.", "code": 0, "status": 401 } } |
Naszym zadaniem jest więc sprawdzenie czy status ciała odpowiedzi (result.status) jest równy 401. Kluczowe jest to, że sprawdzamy status ciała odpowiedzi, nie status zwracanego kodu! Nasz request zawsze zwraca status 200.
No to zaczynamy. Tworzymy prostą strukturę – thread group, http request sampler, dwa listenery (view result tree i assertion results). Do HTTP Request Samplera dodajemy 2 asercje (response i json – json tylko w celach pokazowych, że taka opcja jest). Proste ustawienia – walniemy 2 requesty i sprawdzamy czy status się zgadza.
O ile wynik pozytywnej odpowiedzi nie jest specjalnie ciekawy bo po prostu zwróci nam że wszystko się udało. O tyle jeżeli w oczekiwanych statusach zmienię z 401 na 402, to mam szybki feedback ze strony narzędzia co dokładnie poszło nie tak.
Teraz to już jest Twoja decyzja pod jakim kątem projektujesz testy. Jeżeli testujesz funkcjonalność e2e, chcesz mieć szczegóły, co dokładnie poszło nie tak – projektuj testy tak aby wyciągnąć z nich jak najwięcej informacji. Pobaw się nieco API Jmetera zanim napiszesz finalny test. Zauważ np. że przy JSON Responsie w szczegółach mam informację co zostało zwrócone, natomiast w text response tej informacji już nie ma. Takie szczególiki mogą później być przydatne gdy faktycznie jakieś testy zaczną się sypać a Ty chcesz w miarę przystępnie znaleźć co jest nie tak.
Przetestujmy ograniczenie
Tak jak w poprzednim akapicie – znów będziemy atakowali te same API.
GoRest ogranicza (umożliwia ograniecznie) requestów jakie możemy wysłać do API w przeciągu minuty. Maksymalnie możemy ustawić 60 żądań na minutę. Teraz ustawimy żeby nasze API było atakowane przez 10 użytkowników, 5 razy. Czyli razem 100 requestów (każdy test to 2 requesty – jeden do pobrania wszystkich użytkowników i drugi do pobrania konkretnego).
I tak się prezentują wyniki:
Zauważ że w wyniku Assertion Result, odpowiedzi jakie dostajemy (pomimo użycia Response Assertion) w miarę dokładnie wskazują nam problem, tzn. wyświetlają co było oczekiwane i co przyszło. Dzieje się tak dlatego, że w Response Assertion użyliśmy Custom failure message, gdzie używamy wartości odpowiedzi z JSON Extractora. Oczywiście można by było dodać bardziej szczegółowy output odpowiedzi w przypadku błędu – ja jednak skupiłem się tylko na tym aby zaprezentować Ci, że jest taka możliwość.
Taki jeszcze mały tip do tego wszystkiego. Jeżeli Twoim celem jest zwalidowanie poprawności działania całego flow, gdzie każdy kolejny request jest zależny od poprawności poprzednich kroków to pamiętaj aby włączyć opcję Start Next Thread Loop (opcja w Thread Group). Dzięki temu, jeżeli któraś z Twoich asercji zgłosi błąd – flow aktualngo wątku zostanie przerwane, przez co unikniesz błędów, które w danym teście najprawdopodobniej by się pojawiły.
Jako przykład, załóżmy, że testujesz zakup w sklepie internetowym. Twój test wymagał uwierzytelnienia się, następnie wybrania produktów dostępnych tylko dla zalogowanych klientów a później cały proces zakupu. Coś jednak poszło nie tak w trakcie uwierzytelniania – asercja wywaliła błąd. Jeżeli zaznaczyłeś Start Next Thread Loop to dostaniesz znacznie mniej wyników do analizy, bo kolejne requesty po prostu się nie wykonają. W przeciwnym wypadku całe fłow zostanie wykonane, co oczywiście będzie powodować tylko nowe błędy.
Podsumowanie
JMeter jest potężnym narzędziem i to bez dwóch zdań. Pozwala na pisanie testów funkcjonalnych pod kątem weryfikacji API i w pełni spełnia w tym swoje zadanie. Gdybyś chciał sam potestować to, co opisałem w artykule, to na Githuba wrzuciłem test (pamiętaj aby w HTTP Header Managerze podmienić API key).
Jeżeli temat Cię zainteresował bardziej – bo to co ja opisałem w artykule to jest to tylko wierzchołek góry lodowej – to odsyłam Cię do linków z których sam korzystałem przy tworzeniu tego wpisu:
- User’s Manual – oficjalna dokumentacja JMeter
- JMETER ASSERTIONS: THE ULTIMATE GUIDE
- How to use Assertions in JMeter (Response Example) – krótko i treściwie
Za tydzień
Będzie coś nietypowego – czyli mały agregator (moim zdaniem) najlepszych źródeł do nauki programowania na naszym polskim podwórku. Ps. kiedy post będzie się publikował, ja będę zdobywał Rysy (albo przynajmniej ich podnóżek 😀 )