W miarę rozwoju współczesnego świata IT coraz większa liczba aplikacji i systemów komunikuje się ze sobą za pomocą REST API. To interfejsy programistyczne umożliwiające wymianę danych między aplikacjami poprzez protokół HTTP, odgrywają kluczową rolę w dzisiejszym świecie programowania. Jednak zwiększająca się złożoność danych i interakcji wymaga również bardziej zaawansowanych narzędzi i technik testowania.
W tym kontekście wprowadzenie JSON Schema jako narzędzia do testowania REST API nabiera coraz większego znaczenia. JSON Schema, oparty na języku JSON, umożliwia precyzyjne opisanie struktury i walidacji danych w formacie JSON. Pozwala deweloperom i testerom definiować dokładne oczekiwania co do formatu danych, typów pól, ograniczeń oraz relacji między nimi.
Poniżej znajdziecie przykład, w jaki sposób zaimplementować testy REST API z użyciem JSON Schema. Przykład oparty jest na języku JAVA oraz bibliotece Rest Assured. Na samym końcu artykułu znajdziecie link do repozytorium z gotowym rozwiązaniem.
Implementacja testu bazowego w Rest Assured
Przedmiotem testu stanowić będzie serwis o nazwie reqres.in, który symuluje rzeczywiste scenariusze aplikacji służącej do zarządzania użytkownikami. Jednym z istotnych elementów tego serwisu jest zasób users i właśnie na nim skupimy się teraz, testując poprawność działania jednego z żądań, a mianowicie:
- GET SINGLE USER – https://reqres.in/api/users/2
Do wywoływania żądań w celu ich przetestowania skorzystamy z popularnej biblioteki REST Assured, która pozwala na walidację serwisów REST API w języku JAVA.
Na początek tworzymy klasę testową wraz z metodą testową, która wywoła powyższe żądanie, weryfikując czy zwracany kod odpowiedzi wynosi 200 oraz loguje informacje na temat wywoływanych żądań np. loguje ciało odpowiedzi (response body).
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.when;
public class UserTest {
@Test
public void getUserTest() {
when().
get("https://reqres.in/api/users/2").
then().
statusCode(200).
log().all();
}
}
Wygenerowanie JSON Schema
Kolejny krok to wygenerowanie JSON Schema na podstawie odpowiedzi powstałej po wywołaniu żądania. Najprostszym sposobem na stworzenie schema jest skorzystanie z gotowych generatorów online dostępnych w sieci np. https://extendsclass.com/json-schema-validator.html z jednym ważnym zastrzeżeniem. Jeśli testowane przez was serwisy zawierają jakiekolwiek poufne dane, zrezygnujcie z tego sposób generowania schematów. Zamiast tego użyjcie generatorów tworzących schematy lokalnie na waszych maszynach. Poniżej znajduje się przykładowa lista tego typu narzędzi:
- genson (Python)
- skinfer (Python)
- json_schema_generator (Python)
- genson-js (NodeJS)
- generate-schema (NodeJS)
Nim przejdziemy do wygenerowania schematu, odpowiedzmy sobie na pytanie czym tak naprawdę jest JSON Schema. Jest to język oparty na notacji JSON, który służy do opisywania struktury i walidacji danych w formacie JSON oraz umożliwia tworzenie schematów, czyli wzorców, które określają, jakie pola są wymagane, jakie są ich typy, jakie mogą mieć wartości domyślne, jakie ograniczenia muszą spełniać, a także inne reguły dotyczące danych.
W praktyce JSON Schema umożliwia tworzenie precyzyjnych definicji dla struktury danych, które są wykorzystywane w celu weryfikacji czy dane w formacie JSON spełniają oczekiwane kryteria. Jest to szczególnie użyteczne w aplikacjach, gdzie ważne jest, aby dane były poprawne i zgodne z określonymi standardami.
JSON Schema składa się z kilku kluczowych elementów, które razem tworzą opis struktury i walidacji danych w formacie JSON. Oto główne składniki JSON Schema:
- $schema – określa wersję specyfikacji JSON Schema, z której korzystasz.
Przykład: ” $schema”: “http://json-schema.org/draft-07/schema#”. - type – określa typ danych, które jest reprezentowane przez schemat. Może to być “object” dla obiektów JSON, “array” dla tablic, “string” dla ciągów znaków, “number” dla liczb itp.
- properties – definiuje listę właściwości (pól) dla obiektów JSON. Każda właściwość ma swoje własne właściwości opisujące typ, ograniczenia itp.
- required – zawiera listę nazw właściwości, które są wymagane w obiekcie JSON.
- pattern – określa wyrażenie regularne, które ciąg znaków (string) musi spełniać.
To tylko kilka przykładów kluczowych składników JSON Schema. W rzeczywistości specyfikacja JSON Schema oferuje wiele innych kluczowych pól i możliwości do opisu różnych aspektów danych. Tworząc JSON Schema, możesz korzystać z tych elementów w zależności od potrzeb, aby dokładnie opisać oczekiwany format i walidację danych.
Weźmy na tapetę pierwsze żądanie i wygenerujmy dla niego schemat. Nie zawiera on żadnych poufnych danych, więc skorzystamy z generatora dostępnego online. Po wklejeniu odpowiedzi i kliknięciu przycisku „Generate Schema From JSON” w prawym polu tekstowym zostanie wygenerowana JSON Schema:

Zwróccie uwagę, iż w formularzu istnieje możliwość zaznaczenia checkboxów: required oraz example. Required oznacza, że wszystkie pola znajdujące się w odpowiedzi będą zapisane jako obowiązkowe. Example oznacza zaś, iż w JSON Schema zostaną zapisane przykładowe wartości atrybutów.
Czas na kolejny krok. W folderze src/test/resources
stwórzmy kopie wygenerowanej JSON Schema i nazwijmy ją jako user.json
.
Następnie, aby móc skorzystać z funkcjonalności walidacji schematów typu JSON, koniecznie powinniśmy dodać do projektu następującą bibliotekę/dependencję.
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>json-schema-validator</artifactId>
<version>5.3.0</version>
<scope>test</scope>
</dependency>
Projekt budowany jest w Mavenie, dodajcie więc powyższe linie do pliku konfiguracyjnego pom.xml
.
Dodanie walidacji JSON Schema w metodzie testowej
Czas na dodanie asercji, która sprawdzi czy odpowiedź żądania jest zgodna z wygenerowanym schematem. Nim to zrobimy zaimportujemy metodę walidacyjną o nazwie matchesJsonSchemaInClasspath, a następnie dodamy asercję, dzięki której wskażemy na stworzony przez nas wcześniej plik ze schematem typu JSON.
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.when;
import static io.restassured.module.jsv.JsonSchemaValidator.matchesJsonSchemaInClasspath;
public class UserTest {
@Test
public void getUserTest() {
when().
get("https://reqres.in/api/users/2").
then().
body(matchesJsonSchemaInClasspath("user.json")).
statusCode(200).
log().all();
}
}
To wszystko! Czas na uruchomienie testu. Jeśli poprawnie wykonaliście wszystkie wcześniejsze kroki test powinien zakończyć się sukcesem.
Sprawdźmy teraz co wydarzy się jeśli celowo zmienimy strukturę JSON Schema, w taki sposób, aby test zakończył się niepowodzeniem. W tym celu zmienimy nazwę obowiązkowego atrybutu z avatar na avatar-fail. Po ponownym uruchomieniu testu zakończy się on niepowodzeniem oraz otrzymamy komunikat z następującym błędem:

Na sam koniec podsumujmy jakie główne korzyści niesie za sobą testowanie REST API za pomocą JSON Schema:
JSON Schema pozwala precyzyjnie zdefiniować oczekiwany format i strukturę danych, co sprawia, że testy są dokładniejsze i precyzyjniejsze.
REST API często komunikuje się z innymi serwisami i aplikacjami. JSON Schema pomaga w upewnieniu się, że dane przekazywane między nimi są zgodne z oczekiwaniami, minimalizując ryzyko błędów integracji.
JSON Schema może być używana do automatycznej walidacji danych w testach jednostkowych i testach integracyjnych.
JSON Schema działa jako rodzaj dokumentacji dla testów.
JSON Schema można osiągnąć spójność między oczekiwaniami co do danych a rzeczywistym zachowaniem API. Wszyscy członkowie zespołu korzystają z tych samych definicji, co minimalizuje nieporozumienia.
Stosowanie JSON w testowaniu REST API za pomocą JSON Schema przyczynia się do bardziej konsekwentnych, solidnych i niezawodnych testów, co z kolei pomaga w dostarczaniu wyższej jakości oprogramowania.
Gotowy projekt z rozwiązaniem możecie znaleźć w repozytorium na GitHub Automatyzacja.It.
Jeśli chcielibyście, abym stworzył analogiczne rozwiązanie w innych stack’ach technologicznych np. JS/TS lub C# dajcie znać! 🙂
Aby nie przegapić kolejnego artykułu już teraz zapisz się do Newslettera.