Automatyczne testowanie (IT)Starszy Inżynier Automatyzacji QA

Zaprojektuj zautomatyzowaną strukturę zarządzania, która weryfikuje zgodność wsteczną REST API poprzez porównywanie specyfikacji OpenAPI z umowami konsumentów, egzekwuje zasady wersjonowania semantycznego w pipeline'ach wdrożeniowych oraz generuje macierze wpływu zależności dla usług downstream?

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź na pytanie

Historia: W architekturach monolitycznych zmiany w API były zarządzane poprzez fazy testów integracyjnych. Jednak z przyjęciem mikroserwisów rozprzestrzenienie zależności usług stworzyło "piekło wersjonowania", w którym jedna łamiąca zmiana mogła powodować awarie u dziesiątek konsumentów downstream. To wymusiło przejście od ręcznych przeglądów OpenAPI do zautomatyzowanych bramek walidacyjnych opartych na umowach w ramach pipeline'ów CI/CD.

Problem: Tradycyjne testowanie weryfikuje, czy API działa w izolacji, ale nie wykrywa, czy modyfikacje w schematach żądań/odpowiedzi naruszają niejawne umowy z istniejącymi konsumentami. Ręczne przeglądy specyfikacji są podatne na błędy i nie mogą skalować się w setki wzajemnie powiązanych usług, co prowadzi do incydentów produkcyjnych, gdzie usuwane są przestarzałe pola, które są nadal aktywnie używane.

Rozwiązanie: Wdrożenie wielowarstwowego pipeline'u walidacji integrującego analizę różnic OpenAPI z testami umowy z konsumentami. Wykorzystanie narzędzi takich jak Optic lub Swagger Diff do klasyfikacji zmian jako łamiące (usunięcie pola, zmiany typów) lub niełamiące (opcjonalne dodatki). Integracja Pact w celu weryfikacji, że zmiany dostawcy spełniają oczekiwania zarejestrowanych konsumentów. Egzekwowanie automatyzacji wersjonowania semantycznego, gdzie pipeline oblicza wymagane zwiększenie wersji na podstawie wykrytej powagi zmiany i blokuje wdrożenia, jeśli zwiększenie jest niewystarczające.

validate_api_compatibility: stage: test script: - optic diff openapi.yaml --base main --severity breaking - pact-verifier --provider-app-version $CI_COMMIT_SHA --publish-verification-results - python scripts/check_semver.py --schema-diff-report optic-report.json rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event"

Sytuacja z życia

Nasz zespół utrzymywał API Bramki Płatności, obsługujące dwanaście wewnętrznych mikroserwisów i trzech zewnętrznych partnerów bankowych. Podczas rutynowego ulepszenia w celu dodania pól uwierzytelniających 3D Secure 2.0, jeden z programistów usunął przestarzałe pole transactionReference, zastępując je strukturą obiektową.

Opis problemu: Zmiana przeszła testy jednostkowe i integracyjne, ponieważ nowa struktura prawidłowo obsługiwała dane. Jednak trzy legacy mikroserwisy księgowe nadal oczekiwały płaskiego pola string. Ręczny przegląd OpenAPI przeoczył łamiący charakter tej zmiany strukturalnej. Po wdrożeniu, zadania pojednawcze zakończyły się niepowodzeniem z błędami deserializacji, co spowodowało czterogodzinną przerwę w działaniu.

Rozważane różne rozwiązania:

Manualny przegląd rówieśników z listą kontrolną: Wymóg przeglądu wszystkich zmian OpenAPI przez starszych inżynierów przy użyciu listy kontrolnej łamiących zmian. To podejście polega na ludzkiej czujności, ale jest zasadniczo zawodna pod presją, nie skaluje się z szybkim cyklem wdrożeniowym i nie może uwzględniać ukrytych zależności konsumentów.

Zautomatyzowane porównanie schematu JSON: Wdrożenie podstawowego narzędzia różnicowego, które oznacza wszelkie różnice strukturalne jako błąd. To zapewnia szybkie informacje zwrotne, ale produkuje nadmierne fałszywe pozytywy, traktując zmiany dodawcze (nowe opcjonalne pola) jako naruszenia, zmuszając zespoły do utrzymywania kłopotliwych list wyjątków i ostatecznie ignorowania ostrzeżeń z powodu zmęczenia alertami.

Testowanie umowy z konsumentami z bramkami wersjonowania semantycznego: Wdrożenie Pact dla umów napędzanych przez konsumentów w połączeniu z Optic CLI do analizy różnic OpenAPI. To weryfikuje zmiany w oparciu o rzeczywiste zarejestrowane interakcje z konsumentami, zapewniając, że tylko rzeczywiście łamiące modyfikacje powodują niepowodzenia. Automatycznie sugeruje zwiększenia wersji semantycznej i utrzymuje egzekwowanie harmonogramów usuwania. Minusem jest początkowa inwestycja wymagana do wprowadzenia zespołów konsumentów oraz dodatkowe koszty przechowywania artefaktów umowy.

Wybrane rozwiązanie i uzasadnienie: Wybraliśmy testowanie umowy z konsumentami, ponieważ odpowiadało to potrzebie autonomicznych wdrożeń w naszej architekturze mikroserwisów, jednocześnie zapobiegając kaskadowym awariom. W przeciwieństwie do przeglądów ręcznych, skaluje się poziomo. W przeciwieństwie do podstawowych narzędzi różnicowych, rozumie wpływ semantyczny. Przyjęliśmy koszt onboardingu, nakładając obowiązek testów umowy wyłącznie na krytyczne ścieżki serwisowe początkowo.

Wynik: Łamiące zmiany zostały wyeliminowane z wydań produkcyjnych przez następne osiem miesięcy. Częstotliwość wdrożeń wzrosła z co dwa tygodnie do codziennie, ponieważ zespoły zaufały zautomatyzowanym bramkom. Gdy ta sama zmiana refaktoryzacyjna została podjęta później, weryfikacja Pact nie powiodła się natychmiast w żądaniu scalania, wskazując na niekompatybilność z usługą legacy.

Co często umykają kandydatom

Jak rozróżniasz zmiany syntaktyczne łamiące i zmiany semantyczne łamiące w walidacji REST API?

Zmiany syntaktyczne obejmują modyfikacje strukturalne, które można wykryć poprzez różnicowanie schematów OpenAPI, takie jak usunięcie pola lub zmiana typu. Zmiany semantyczne zachowują strukturę, ale zmieniają zachowanie, na przykład zmieniając wartość domyślną opcjonalnego parametru lub modyfikując kolejność sortowania zwracanych tablic. Czysta walidacja schematu przeocza łamiące zmiany semantyczne, wymagając testowania behawioralnego za pomocą testów umowy lub porównań ruchu cieniowego, aby wykryć zmienione wyniki logiki biznesowej.

Czym jest wzór rozwijania-zwijania i jak automatyzacja powinna go egzekwować?

Wzór rozwijania-zwijania wymaga dodania nowej funkcjonalności obok starej (rozszerzyć), migracji konsumentów, a następnie usunięcia starego kodu (zwiń). Automatyzacja musi śledzić metadane wycofania pól z datami końcowymi, powodując błędy budowy, jeśli przestarzałe pola zostaną usunięte przedwcześnie. Dodatkowo system powinien monitorować telemetrię w celu weryfikacji braku ruchu na przestarzałych punktach końcowych przed pozwoleniem na usunięcie, co zapewnia prawdziwą gotowość konsumentów, a nie tylko zgodność na poziomie kodu.

Jak weryfikować zgodność API, gdy konsumenci są zewnętrznymi stronami trzecimi, które nie mogą uczestniczyć w twoim pipelineie testowania umów?

Dla zewnętrznych konsumentów, gdzie dwukierunkowe umowy Pact są niemożliwe, wdrożenie symulacji syntetycznych konsumentów przy użyciu cieniowania ruchu i testów VCR. Rejestrowanie wzorców produkcyjnych w celu stworzenia reprezentatywnych mocków, a następnie odtwarzanie ich w stosunku do nowych wersji API. Połączenie tego z canary deployments z automatycznymi wyzwalaczami rollbaku oraz utrzymywanie rygorystycznych polityk LTS dla publicznych API z obowiązkowymi powiadomieniami o wycofaniu rozciągającymi się na kilka kwartałów.