Co można robić w tawernie? Pić, jeść, słuchać opowieści starych marynarzy lub… testować API! Jeśli wykonywanie tej czynności w portowej karczmie wydaje się Wam zaskakujące, to najwyraźniej nie słyszeliście jeszcze o pythonowym frameworku Tavern, służącym właśnie do testów API. To zaś oznacza, że prawdopodobnie warto poświęcić krótką chwilę na lekturę niniejszego wpisu.

„Scena w tawernie”, David Teniers, 1658

Załóżmy, że chcemy przetestować API, zawierające między innymi endpointy POST /users oraz GET /users/{user_id}. Aby łatwiej nam było eksperymentować, użyjmy do tego jakiejś prostej implementacji, np.:

Kod ten zawiera kilka błędów, co przyda nam się przy jego testowaniu. Jak zrobić to przy użyciu biblioteki Tavern? Serwowany nam przez jej twórców pomysł polega na wykorzystaniu języka YAML do definiowania przypadków testowych. Nie piszemy kodu odpowiedzialnego za wysyłanie zapytań HTTP, lecz w przejrzysty sposób deklarujemy co chcemy zweryfikować i jakich danych należy użyć. Jeden z naszych testów, sprawdzający poprawność dodawania nowego użytkownika, mógłby więc wyglądać tak:

Test składa się z dwóch etapów: w pierwszym wysyłamy request POST, dodając użytkownika o uprawnieniach administratora, zaś w drugim, przy pomocy metody GET, pobieramy dane o tym użytkowniku.

W sekcjach request podajemy dane, które mają zostać wysłane do serwera (w naszym przykładzie w formacie JSON), metodę HTTP oraz adres endpointu, natomiast w response definiujemy oczekiwany kod statusu i określamy co spodziewamy się otrzymać w odpowiedzi.

Dla przykładu, w piewszym kroku wymagamy, aby serwer zwracał te same wartości, które zostały mu przekazane w zapytaniu, a dodatkowo chcemy otrzymać wygenerowany przez niego identyfikator, który ma być liczbą całkowitą (!anyint).

Zmienne, które potrzebujemy przekazywać pomiędzy różnymi krokami, zapisujemy, używając sekcji save:. Tym sposobem po otrzymaniu pierwszej odpowiedzi z serwera zapamiętujemy user_id i używamy go, wykonując kolejne zapytanie.

Zanim przystąpimy do odpalenia testu, konieczne będzie jeszcze zdefiniowanie pliku common.yaml, który załączyliśmy w czwartej linii. Jest to nasz plik pomocniczy, w którym ustawiamy dane, wykorzystywane w wielu różnych testach, takie jak adres serwera, przykładowe dane itp.

Teraz, kiedy mamy już wszystko, włączmy nasz prosty serwer, zapiszmy test jako test_create_admin_user.tavern.yaml, i zlećmy jego wykonanie komendą tavern-ci test_create_admin_user.tavern.yaml. Naszym oczom powinien ukazać się błąd, ponieważ, o czym już wspomniałem, nasze API zawiera bugi. Wydrukowany przez Tavern komunikat powinien pozwolić na zidentyfikowanie błędnego fragmentu, ale czy naprawdę konieczne jest zalewanie użytkownika setkami linii?

Na ten problem zwrócił w swoim wpisie uwagę również Alessandro Pagiaro. Opisał też kilka innych utrudnień, których świadomość należy mieć, decydując się na użycie tego frameworka. Od siebie dodam też, że sama dokumentacja nie jest przesadnie obszerna i nie zachwyca swoją dokładnością ani liczbą przykładów, przez co do niektórych rozwiązań trzeba docierać samodzielnie.

Warto natomiast zaznaczyć, że potrzebując wykonać bardziej skomplikowane operacje niż te obsługiwane na poziomie kodu w YAML-u, można zakodować je w Pythonie. Na przykład jeśli w celu autoryzacji musimy dokonać jakichś obliczeń, to możemy wrzucić je do pliku conftest.py:

a następnie odnieść się do tak zaimplementowanej funkcji wewnątrz testu:

Do pythonowego kodu możemy też oddelegować sprawdzanie co bardziej skomplikowanych warunków w otrzymywanych ze strony API odpowiedziach.

Chociaż tworzonym w Tavern testom nie sposób odmówić czytelności, to osobiście i tak nie wybrałbym tego rozwiązania. Zdecydowanie wolę wyzbyć się wszelkich ograniczeń i bezpośrednio korzystać chociażby z pythonowego modułu unittest lub nawet pytest (który to jest bazą dla frameworka Tavern). Jeśli jednak z jakiegoś powodu bardziej przemawia do Ciebie pisanie testów w YAML-u lub użycie Tavern sprawdziło się w Twoim projekcie, zachęcam do podzielenia się swoimi doświadczeniami!

Linki

  1. Tavern – oficjalna strona.
  2. Tavern – dokumentacja.
  3. How to test a RESTful API, A. Pagiaro.
.