Wprowadzenie
Postman jest genialnym narzędziem, bez którego nie wyobrażam sobie pracy nad WebApi. Kilka miesięcy temu opisywałem na blogu, jak testować api z wykorzystaniem Postmana. Pokazałem, jak wysyłać żądania, używać zmiennych oraz zapisywać testowe żądania w kolekcje. Oczywiście Postman oferuje o wiele więcej. W tym wpisie pokażę Ci, jak można wykorzystać asserty w Postmanie do automatycznych testów, aby wykonywać je później w ramach CI/CD. Dzięki temu możemy mieć większą pewność, że czegoś niechcący nie popsuliśmy w aplikacji.
Przykład do testów
Na potrzeby tego wpisu przygotowałem proste WebApi, w którym znajduje się ProductsController. Zawiera on podstawowe operacje (CRUD) na produktach (tylko nazwa produktu) w aplikacji. Nie dzieje się tam nic wielkiego i ciekawego. Podobne wersje przykładu były używane w innych wpisach, dlatego samej testowej aplikacji nie będę opisywał w tym wpisie. Zachęcam do przejrzenia WebApi na githubie – https://github.com/danielplawgo/WebApiTests.
Postman Asserty
Tytułowe asserty do żądania w Postmanie możemy dodać w zakładce Test w górnej części okna (numer 1 na zrzucie ekranu):
W edytorze możemy pisać kod (jest to JavaScript), który wykona się po otrzymaniu odpowiedzi z serwera. W kodzie głównie znajdują się asserty sprawdzające różne właściwości odpowiedzi. Możemy sprawdzić status odpowiedzi, czas obsługi żądania, dane, które odesłał serwer, czy inne rzeczy, które mogą się nam przydać.
Po prawej stronie edytora (punkt 2) znajduje się lista przykładowych snippetów, dzięki której w łatwy sposób możemy dodawać nowe asserty (ale nie tylko je). Udostępnione snippety pokrywają większość scenariuszy, które mogą przydać się nam w trakcie tworzenia testów do żądań.
Pierwsze testy
Na zrzucie ekranu widać żądanie (do adresu {{url}}/api/products/1), które pobiera informacje o produkcie o określonym id (równym 1). W adresie użyłem zmiennej środowiskowej, po to, abym mógł wysyłać żądanie do różnych środowisk, które wykorzystujemy w projekcie.
Do przykładowego żądania dodałem trzy testy:
pm.test("Status code is 200", function () { | |
pm.response.to.have.status(200); | |
}); | |
pm.test("Response time is less than 200ms", function () { | |
pm.expect(pm.response.responseTime).to.be.below(200); | |
}); | |
pm.test("Return added product data", function () { | |
var jsonData = pm.response.json(); | |
pm.expect(jsonData.Success).to.eql(true); | |
pm.expect(jsonData.Value.Id).to.eql(1); | |
pm.expect(jsonData.Value.Name).to.eql("Name1"); | |
}); |
Pierwszy sprawdza status (200) odpowiedzi, drugi sprawdza czas odpowiedzi (poniżej 200 ms), natomiast ostatni deserializuje dane z jsona oraz sprawdza właściwości obiektu. Ostatni test mogę zapisać trochę inaczej i sprawdzić, czy zwrócony json ma określoną wartość:
pm.test("Return added product data", function () { | |
pm.response.to.have.body('{"Value":{"Id":1,"Name":"Name1"},"Success":true,"Errors":[]}'); | |
}); |
W różnych sytuacjach używam jednego lub drugiego. Na ogół używam drugiego podejścia (czyli sprawdzanie całego jsona). Wtedy testy pisze się szybciej i zajmują one mniej miejsca. Natomiast pierwszego podejścia używam w sytuacji, gdy chcę sprawdzić tylko określone wartości w odpowiedzi. Dzięki temu zmiana czegoś w innych miejscach odpowiedzi nie powoduje, że muszę aktualizować wszystkie testy.
Po wykonaniu testów w dolnej części okna, w zakładce Test Results zobaczymy wyniki poszczególnych testów. Na powyższym zrzucie widać to w punkcie 3, gdzie wszystkie testy „przeszły”.
Warto dodać jeszcze, że obok zakładki Tests w definicji żądania mamy również drugą zakładkę Pre-request Script, w której także możemy dodawać kod JavaScript. Kod ten wykona się przed wysłaniem żądania do serwera. Możemy więc coś przygotować wcześniej i później wykorzystać to w kodzie wykonywanym po żądaniu.
Używanie zmiennych
W testach poza assertami możemy robić jeszcze inne rzeczy. Jedną z ciekawych opcji jest możliwość ustawiania zmiennych w Postmanie (np. zmiennych środowiskowych). Dzięki temu możemy sobie przekazywać wartości z jednego żądania do drugiego.
Na ogół wykorzystuję to w testach akcji, które coś dodają do aplikacji lub modyfikują ją. W przykładzie wykorzystałem to w testach akcji dodającej nowy produkt do aplikacji. W odpowiedzi otrzymuję Id dodanego produktu. Zapisuję go w zmiennej o nazwie productId, co widać poniżej:
Następnie mogę z tej zmiennej skorzystać w innym żądaniu i na przykład spróbować pobrać z api nowo dodany produkt:
Jest to bardzo przydatne, gdy budujemy jakiś zbiór testów wykonujących jakąś sekwencję działań, gdzie poszczególne żądania zależą od siebie.
Organizacja żądań w kolekcji
Zanim pokażę Ci, w jaki sposób uruchomić zbiór testów z wykorzystaniem Runnera, parę słów na temat tego, w jaki sposób organizuję sobie testy w kolekcji. Widać to na zrzucie:
Rozdzielam zapisane żądania na dwa foldery. Pierwszy folder, Dev, wykorzystuję podczas normalnej pracy nad WebApi. Natomiast w drugim, Automatic, znajdują się żądania z assertami, które są uruchamiane automatycznie później, np. w procesie CI/CD, i które weryfikują, czy czasem czegoś nie popsuliśmy.
W obu folderach mam podfoldery dla poszczególnych kontrolerów mojej aplikacji. W przypadku folderu Automatic jeden taki folder zawiera scenariusz, który chcę automatycznie testować. Dlatego w nim bardzo często powtarzają się żądania do tych samych akcji.
Tak jak widać na powyższym zrzucie, w folderze Automatic/Products znajduje się 5 razy żądanie do akcji zwracającej produkt na podstawie Id. Są one wywoływane w różnym momencie całego scenariusza testu. Na przykład pierwsze żądanie sprawdza, czy WebApi zwróciło dane produktu, który jest w testowej bazie. Natomiast drugie żądanie sprawdza, czy produkt został dodany w odpowiedni sposób.
W folderze Automatic czasami mam jeszcze dodatkowe foldery, które testują bardziej rozbudowane scenariusze wykorzystujące akcje z różnych kontrolerów.
Możesz jeszcze zauważyć, że pierwsze żądanie (Reset Test Data) w folderze Automatic/Product jest nieco dziwne. W tego typu testach zakładamy, że mamy jakiś z góry ustalony stan naszej aplikacji. Ta akcja właśnie przywraca stan aplikacji do tego znanego punktu. Dzięki temu testy będziemy mogli wielokrotnie powtarzać, bez konieczności ręcznego czyszczenia danych. Do tego tematu wrócę jeszcze w przyszłych wpisach.
Uruchamianie testów z folderów
W górnej części okna Postmana znajduje się przycisk Runner, który umożliwia uruchomienie wielu żądań:
Sam runner wygląda tak:
W lewej części okna znajduje się struktura folderów z kolekcjami (punkt 1), w której wybieramy folder z testami, które chcemy uruchomić. Po prawej stronie (punkt 2) znajduje się lista testów do uruchomienia. Domyślna kolejność jest taka, jak kolejność testów w folderze. Tutaj możemy jeszcze zmienić kolejność przed uruchomieniem testów lub odznaczyć jakieś żądania, aby się nie wykonały.
Pod listą folderów możemy skonfigurować sposób wykonywania żądań. Wybieramy środowisko, dla którego chcemy wykonać testy (punkt 3). Możemy też skonfigurować inne opcje, jak na przykład liczbę iteracji.
Uruchamiamy wszystko z wykorzystaniem przycisku Run Automatic (punkt 4). W efekcie otrzymamy coś takiego:
W górnej części okna znajduje się podsumowanie wyników testów. Na zrzucie widać, że „przeszło” 37 testów i żaden nie skończył się błędem. Niżej znajduje się lista poszczególnych żądań z informacjami o ich testach.
Przykład
Tradycyjnie na githubie umieściłem przykład do tego wpisu: https://github.com/danielplawgo/WebApiTests. Jest w nim sama testowa aplikacja oraz kolekcja Postmana z testami. Do uruchomienia aplikacji niczego nie potrzebujesz. Wystarczy pobrać kod i uruchomić jak w Visual Studio.
Podsumowanie
Postman jest narzędziem, które powinien znać każdy programista tworzący api. Wykonywanie automatyczne testów do żądań powoduje, że dość łatwo możemy zbudować sobie zbiór testów, które uruchamiane regularnie dadzą nam większą pewność, że nasza aplikacja działa poprawnie. W przyszłych wpisach wrócę jeszcze do tego tematu i poruszymy inne zagadnienia związane z takimi testami w Postmanie.
1 thought on “Postman – asserty w automatycznych testach”