Wprowadzenie
Publikowałem na blogu już kilka wpisów na temat testowania API z wykorzystaniem świetnego narzędzia jakim jest Postman. W tym w jaki sposób automatycznie testować API podczas każdego release w Azure DevOps. W tym wpisie natomiast chciałbym przedstawić alternatywę dla takich testów, w postaci narzędzia Karate.
Karate
Karate jest narzędziem, za pomocą którego możemy wykonać różnego rodzaju testy. Od testów API, które pokażę Ci w tym wpisie, po testy interfejsu użytkownika, czy testy wydajnościowe. Karate jest tworzone w javie, ale co ważne znajomość tego języka i całego ekosystemu nie jest konieczna. Jak później zobaczysz, wystarczy nam tylko środowisko uruchomieniowe javy (jre).
Twórcy Karate wykorzystali podejście BDD (Behavior-Driven Development) do opisywania poszczególnych testów. Co jest ubrane w format Given… When… Then… A przykładowy test wygląda w ten sposób:
Scenario: Login | |
Given url "run.cmd" | |
And request {"Username":"userName","Password":"password"} | |
When method POST | |
Then status 200 |
W pliku tym znajduje się scenariusz dla logowania, w którym dla adresu url oraz jsona wykonujemy żądanie typu POST i oczekujemy statusu odpowiedzi 200.
Dzięki takiemu formatowi testów, po pierwsze są one łatwe w zrozumieniu i nie wymagają znajomości javy, a po drugie dużo łatwiej nimi zarządzać w repozytorium niż wyeksportowanymi kolekcjami z Postmana.
Karate jest rozbudowanym narzędziem z bardzo fajną dokumentacją na githubie projektu – https://github.com/intuit/karate
API do testów
Narzędzie najlepiej poznać na jakimś przykładzie (dostępny w repozytorium dla tego wpisu – https://github.com/danielplawgo/KarateTests). Dlatego utworzyłem proste API, które składa się z dwóch akcji:
- /api/Auth/Login – logowanie użytkownika – akcja zwraca token JWT
- /api/products/{id} – zwrócenie produktu o określonym id
Testowe API nie jest jakoś mocno rozbudowane i samo zrozumienie jego kodu nie jest potrzebne na potrzeby poznania Karate.
Środowisko pracy
Z racji tego, że Karate jest napisane w javie, to sporo miejsca w dokumentacji jest poświęcone temu, jak zorganizować testy w projekcie javy. Z racji tego, że na co dzień pracuję w .NET, to potrzebowałem rozwiązania, które minimalizuje konieczność korzystania z javy. Na szczęście twórcy narzędzia udostępniają je w formie pojedynczego pliku, który można uruchomić z poziomu wiersza poleceń. Wymagane jest tylko środowisku uruchomieniowe javy (jre).
Co fajne do Visual Studio Code dostępny jest dodatek Karate Runner (https://marketplace.visualstudio.com/items?itemName=kirkslota.karate-runner), który umożliwia uruchamianie poszczególnych testów bezpośrednio z poziomu Visual Studio Code:
Osobiście używam właśnie to IDE do tworzenia testów.
Struktura projektu
Dla testów przygotowujemy dedykowany folder, w którym musimy ręcznie dodać kilka plików. W testowym projekcie, który przygotowałem na potrzeby tego wpisu, wygląda to tak:
W folderze src znajdują znajdują się testy. Są one grupowane w pliki *.feature, a poszczególne testy w środku są jeszcze dodatkowo grupowane w scenariusze. W tym miejscu możemy mieć rozbudowaną strukturę folderów/plików w zależności od skomplikowania API.
Do folderu target zapisywane są wyniki wykonania testów. Znajdują się tam głównie htmle z raportami, które na przykład później możemy wrzucać sobie do Azure DevOps, aby widzieć, co się wykonało, a co nie.
W pliku environment-config.json trzymam konfigurację testów, aby w samych testach nie harcodować różnych wartości na przykład adresu url API, jakiegoś loginu/hasła itp, które mogą mieć inne wartości dla różnych środowisk. W przykładzie wygląda on tak:
BaseUrl umożliwi nam później budowanie względne adresów w samych testach. Później podczas uruchamiania testów w Azure DevOps będę tę wartość nadpisywał na adres właściwego środowiska (np. test, stage, prod). Pozostałe dwa pola to testowy login i hasło.
Plik karate.jar to właśnie nasze narzędzie, a run.cmd służy do jego pobrania i wykonuje testy z poziomu wiersza poleceń. Jego zawartość to:
curl -L https://github.com/intuit/karate/releases/download/v0.9.6/karate-0.9.6.jar --output karate.jar | |
java -jar karate.jar -t ~@ignore src |
W drugiej linijce jest wykonanie naszych testów. Parametr -t określa tagi, które mają być wykonane (poszczególne testy możemy tagować). W tym przypadku uruchamiamy wszystkie testy, które nie mają tagu ignore. Na końcu określamy folder z testami.
Plik run.cmd wykorzystuję głównie w Azure DevOps (o czym w kolejnym wpisie).
karate-config.js
Ostatni plik do omówienia do karate-config.js. Jest on tutaj najbardziej istotny, ponieważ jest punktem startowym do wykonywania testów. W nim możemy przygotować konfigurację testów, określić jakieś wspólne elementy, czy generalnie wykonać jakiś fragment kodu na samym początku.
W przykładzie jego zawartość to:
Na początku wczytujemy dane z environment-config.json, o którym pisałem wyżej. W kolejnym kroku wykonuję specjalny test z pliku src/Auth.feature. Jest to test logowania użytkownika do aplikacji (poniżej jego dokładny opis). W tym przypadku ten test zwróci nam uzyskany token JWT, który jest wykorzystany w kolejnym kroku.
Za pomocą metody karate.configure możemy skonfigurować sobie w tym miejscu globalnie wszystkie żądania wysyłane do serwera. W tym przypadku ustawiam token JWT w nagłówku, dzięki czemu nie będę musiał tego robić w poszczególnych testach. Będą one czytelniejsze i łatwiejsze w analizie.
Na końcu zwracamy obiekt konfiguracji, będzie on dostępny później w każdym teście.
Auth.feature
W tym pliku znajduje się test logowania:
Feature: Auth - fetching jwt token | |
Background: | |
* url baseUrl+"/api/Auth/Login" | |
Scenario: Featch jwt token | |
Given request {"Username":"#(userName)","Password":"#(password)"} | |
When method POST | |
Then status 200 | |
And match response contains { "message": "Success" } | |
* def token = response.token |
Feature, jak pisałem, służy nam do grupowania testów, co później będzie widoczne na przykład w raportach. Osobiście na ogół mam jeden plik feature dla każdej akcji w API.
Za pomocą Background możemy określić jakieś wspólne kroki, które będą wykonywane przed każdym scenariuszem w danym pliku. W tym przypadku określam adres url, pod który będą wysyłane żądania, dzięki czemu nie będę musiał tego określać w każdym żądaniu. A co za tym idzie testy będą krótsze i łatwiejsze do analizy.
W pliku znajduje się jeden scenariusz (pobranie tokenu JWT), który wysyła żądanie POST z jsona zawierające login i hasło, a następnie sprawdza status odpowiedzi i jej zawartość.
W odpowiedzi sprawdzam, czy zawiera ona pole message z wartością Success. Karate udostępnia rozbudowane asserty, które są opisane w dokumentacji.
Podczas definicji jsona do wysłania wykorzystałem składnię #(nazwa_pola), która umożliwia pobranie wartości pola o przekazanej nazwie z obiektu, który został zwrócony w pliku karate-config.js. Dzięki czemu nie musimy na sztywno wrzucać tutaj konkretnych wartości.
Na końcu definiowane jest pole token, do którego wrzucamy token z odpowiedzi. To jest właśnie to pole z tokenem JWT, które później ustawiliśmy w nagłówku w pliku karate-config.js.
GetProduct.feature
W drugim pliku jest test pobrania danych produktu:
Jest on bardzo podobny do wcześniejszego testu. Różnica jest głównie w assercie. Wcześniej korzystaliśmy z operatora contains, który sprawdzał, czy odpowiedz zawierała dane pole. Tutaj natomiast skorzystałem z operatora porównania (==), który sprawdza, czy odpowiedź jest identyczna z wzorcem.
Jak wspomniałem karate udostępnia rozbudowane asserty.
Wykonanie testów
Poszczególne testy możemy wykonywać bezpośrednio z poziomu Visual Studio Code po zainstalowaniu dodatku Karate Runner. Możemy również wykonać je bezpośrednio z wiersza poleceń:
java -jar karate.jar -t ~@ignore src |
W efekcie na konsoli otrzymamy informacje o każdym z testów (na przykład zawartość żądania i odpowiedzi), a na końcu podsumowanie (poniżej screen z końcowym fragmentem wyniku):
Dodatkowo w folderze target znajdują się wygenerowane raporty html:
Są one generowane w dwóch formatach. Dla przykładu Cucumber report:
Taki raport później możemy wrzucić sobie na przykład do Azure DevOps.
Przykład
Na githubie (https://github.com/danielplawgo/KarateTests) znajduje się kod przykładu. Jest w nim testowe API oraz testy karate. Po pobraniu przykładu należy w pierwszej kolejności uruchomić API z poziomu Visual Studio, a później testy za pomocą run.cmd.
Podsumowanie
Karate jest bardzo fajnym narzędziem, które w tym momencie zastępuje u mnie automatyczne testy z Postmana. Możliwości są rozbudowane, a pracuje mi się trochę przyjemniej niż z Postmanem. Postmana dalej używam do pracy i wykonywania pojedynczych żądań do API.
A co ty myślisz o karate?
1 thought on “Karate – automatyczne testy API”