To mnie niepokoi od dłuższego czasu. Czy faktycznie warto testować jednostkowo klienta API?
Załóżmy, że tworzysz małą klasę, aby odciąć połączenia do interfejsu API REST sklepu zoologicznego. Petshop jest bardzo prostym API i ma podstawowy zestaw metod:
listProducts()
getProductDetails(ProductID)
addProduct(...)
removeProduct(ProductID)
Podczas testowania musielibyśmy stworzyć próbną usługę lub kpić z odpowiedzi. Ale to wydaje się przesadą; Rozumiem, że chcemy się upewnić, że nasze metody nie przestają działać z błędami literówek / składni, ale ponieważ piszemy funkcje wywołujące metody zdalne, a następnie tworzymy fałszywe odpowiedzi z tych metod zdalnych, wydaje się, że strata wysiłku i że testujemy coś, co tak naprawdę nie może zawieść. Co gorsza, jeśli zdalna metoda ulegnie zmianie, nasze testy jednostkowe zakończą się niepowodzeniem, gdy użycie produkcyjne się nie powiedzie.
Jestem prawie pewien, że coś mi umknęło, że mam niewłaściwy koniec kija lub nie widzę drewna na drzewa. Czy ktoś może ustawić mnie na dobrej drodze?
źródło
Odpowiedzi:
Zadaniem zdalnego klienta API jest wykonywanie określonych połączeń - nie więcej, nie mniej. Dlatego jego test powinien zweryfikować, czy wykonuje te połączenia - nie więcej, nie mniej.
Jasne, że jeśli dostawca interfejsu API zmieni semantykę swoich odpowiedzi, wówczas system zawiedzie w produkcji. Ale to nie wina twojej klasy klienta; jest to coś, co można złapać tylko w testach integracyjnych. Opierając się na kodzie, który nie jest pod twoją kontrolą, zrezygnowałeś z możliwości weryfikacji poprawności za pomocą testów wewnętrznych - to była kompromis, a taka jest cena.
To powiedziawszy, testowanie klasy składającej się wyłącznie z delegacji do innej klasy może mieć niski priorytet, ponieważ ryzyko złożonych błędów jest stosunkowo niewielkie. Ale dotyczy to każdej klasy, która składa się tylko z jednolitych jednowarstwowych, nie ma to nic wspólnego z wywoływaniem kodu innego dostawcy.
źródło
foo()
zostanie wywołane wcześniejbar()
, ale to nie znaczy, że dzwonieniefoo()
wcześniejbar()
jest właściwą rzeczą; taki test jednostkowy byłby pozytywny, nawet jeśli kod jest niepoprawny. A jeśli to wszystko, co robi klient, konfigurowanie prób sprawdzających, czy ktośfoo()
zostanie wcześniej wywołany,bar()
jest stosunkowo kłopotliwe dla czegoś, co można zweryfikować pobieżnym spojrzeniem na kod klienta.add()
metoda poprawnie dodaje dwie liczby, ale to nie znaczy, że dodawanie jest właściwą rzeczą do zrobienia w tym punkcie algorytmu -add()
test jednostkowy powiódłby się, nawet jeśli twój program się pomylił. Jeśli jest to niewłaściwa rzecz, to twojalevenshteinDistance()
metoda jest winna, a nieadd()
metoda. To jest dokładnie to samo. Kluczem do rozdzielenia kodu na metody jest zawsze to, że każda metoda musi dbać tylko o poprawienie jednej rzeczy.Krótka odpowiedź:
Wszystkie metody powinny być testowane jednostkowo.
Długa odpowiedź:
Tak. Jest tego warte.
Oto niektóre rzeczy, które powinny przetestować testy jednostkowe tych metod wywoływania API:
Są to rzeczy, które robią wywoływane metody, które można odizolować, kpiąc sobie z usługi API i że poprzez ich dobre przetestowanie, zapewniamy, że błędy nie powstają w wyniku błędu w kodzie klienta, który wywołuje API.
źródło
Nie byłyby to testy jednostkowe, ponieważ testujesz dane wejściowe i wyjściowe systemu, bardziej jak ograniczone testy integracyjne.
Bądź bardzo ostrożny, gdy mówisz „wydaje się to stratą wysiłku i że testujemy coś, co nie może naprawdę zawieść” - może zawieść, zawiedzie, prawdopodobnie zawiedzie w sposób, którego nie można przewidzieć, awarie będą gorsze, jeśli nie przeprowadzisz testów.
Błąd, który popełniacie tutaj, polega na wymyśleniu kół: wykonywanie połączeń do zdalnych usług i interfejsów API jest bardzo częstym scenariuszem, więc istnieje kilka całkiem dobrych narzędzi, które pomogą ci to przetestować. Ostatnim razem pracowałem nad aplikacją, która łączyła się ze zdalnymi usługami, korzystałem z SoapUIktóre mogą patrzeć na usługę i albo wykonywać fałszywe połączenia z tą usługą, albo zachowywać się jak lokalna kopia serwera, na której można wykonywać połączenia testowe i śledzić żądania i odpowiedzi. Konfiguracja zajęła kilka minut, a aktualizacja bardzo szybko przebiegała, jeśli zmienił się interfejs zdalny. Nie użyłem go w scenariuszu REST, ale nawet jeśli to nie działa dobrze (lub może ktoś czyta tę odpowiedź w przyszłości, gdy będą istniały lepsze narzędzia), powinieneś być w stanie znaleźć narzędzie, które może naśladować usługa dla Ciebie, a kiedy przyjdzie czas na wdrożenie kodu, będziesz zadowolony, że to zrobiłeś.
źródło