Karate – automatyczne testy API

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

Darmowy kurs Visual Studio

Pracując z setkami programistów, zauważyłem, że większość osób nie pracuje efektywnie w Visual Studio. W skrajnych przypadkach korzystali z kopiowania z wykorzystaniem menu Edit. Wiem, że to dziwne, ale naprawdę niektórzy tak pracują. Dlatego postanowiłem stworzyć kurs Visual Studio – aby pomóc koleżankom i kolegom w efektywniejszej pracy.

Przygotowałem 30 lekcji e-mail, w których pokażę Ci, w jaki sposób pracować efektywniej i szybciej w Visual Studio. Poznasz dodatki, bez których nie wyobrażam sobie pracy w tym IDE.

Po więcej informacji zapraszam na dedykowaną stronę kursu: Darmowy Kurs Visual Studio.

Quiz C#

Ostatnio przygotowałem również quiz C#, w którym możesz sprawdzić swoją wiedzę. Podejmiesz wyzwanie?

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:

Uruchamianie testów 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:

Struktura projektu karate

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
view raw run.cmd hosted with ❤ by GitHub

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
view raw Auth.feature hosted with ❤ by GitHub

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
view raw cmd hosted with ❤ by GitHub

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):

Wynik wykonania testów

Dodatkowo w folderze target znajdują się wygenerowane raporty html:

Raporty w folderze target

Są one generowane w dwóch formatach. Dla przykładu Cucumber report:

Raport Cucumber z wynikami testów

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?

Szkolenie Automatyczne testy w .NET 5

SzkolenieAutomatyczne testy w .NET 5

Zainteresował Ciebie ten temat? A może chcesz więcej? Jak tak to zapraszam na moje autorskie szkolenie o automatycznych testach w .NET..

1 thought on “Karate – automatyczne testy API

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.