Contract testing: Čo to je, ako funguje a kedy ho nasadiť

Contract testing je metóda softvérového testovania, ktorá overuje, či spolu consumer a provider služba komunikujú v súlade so zdieľaným kontraktom – teda dohodou o formáte requestov a responses. Na rozdiel od integration testingu sa testy spúšťajú nezávisle na oboch stranách a nevyžadujú bežiace prostredie druhej služby.

Traja kolegovia pri notebookoch pod schémou prepojenia consumer služby, kontraktu pact.json a provider služby.
Pact overuje, či provider služba spĺňa očakávania zapísané v kontrakte.

V článku sa dozvieš:

    Ako contract testing funguje

    Contract testing beží v dvoch krokoch. Consumer zapíše očakávania voči provider API do kontraktu, provider ho potom overí voči svojej implementácii.

    Kontrakt je JSON alebo YAML dokument s očakávanými requestmi a responses. Namiesto spúšťania provider služby stačí táto zapísaná dohoda.

    Rozlišujú sa dva typy testov. Consumer-side test overuje, či consumer vie pracovať s dátami podľa kontraktu. Provider-side test, tzv. verifikácia, overuje, či provider implementácia vracia to, čo kontrakt sľubuje.

    Kontrakt zároveň definuje formát REST API odpovede vrátane štruktúry JSON tela, statusových kódov a hlavičiek, čo je jadro celého princípu.

    Ak sa formát nezhoduje, test zlyhá pred nasadením a tím presne vidí, ktorá časť kontraktu nesedí, napríklad chýbajúce pole alebo iný dátový typ.

    Čím sa contract testing líši od iných typov testovania

    Contract testing sa v praxi často zamieňa s API testingom, integration testingom a component testingom. Rozdiely sú jemné, no rozhodujú o tom, čo presne test odhalí.

    Contract testing vs API testing: je to naozaj to isté?

    Nie. API testing overuje funkčnosť celého API zvonka, kým contract testing overuje len to, či sa consumer a provider zhodujú na formáte komunikácie.

    API testing preveruje endpoint dôkladne: kontroluje business logiku, autentifikáciu aj chybové stavy. Contract testing sa sústreďuje len na štruktúru dát medzi stranami a beží nezávisle od toho, či je druhá služba spustená.

    Predstav si mikroslužbu, ktorá vracia zoznam objednávok. API test overí, že endpoint vráti správne dáta aj pri chybnom vstupe. Contract test sa spýta iba na jedno: či pole s cenou je typu number, a nie reťazec.

    Kritérium API testing Contract testing
    Čo overuje funkčnosť a správanie celého API zhodu formátu requestu/response medzi consumer a provider
    Potrebuje bežiace prostredie áno, oboch strán nie, beží nezávisle na oboch stranách
    Typický rozsah celý endpoint, business logika len štruktúra dát a kontrakt

    Contract testing vs integration testing

    Integration testing overuje, či spolu fungujú reálne bežiace komponenty, kým contract testing to isté overí bez toho, aby druhá služba vôbec bežala.

    Integration testing potrebuje bežiace prostredie oboch strán súčasne, je preto pomalší a krehkejší. Na rozdiel od neho beží contract testing izolovane a rýchlejšie, pretože sa spolieha len na zapísaný kontrakt.

    V praxi sa oba prístupy dopĺňajú: contract testing zachytí nesúlad formátu skôr, ešte pred integračným testom. Ak napríklad provider zmení dátový typ poľa „status“, contract test to zachytí okamžite, integration test až pri behu systému.

    Contract testing vs component testing

    Component testing overuje jednu službu izolovane od zvyšku systému. Naopak, contract testing sa zameriava presne na rozhranie medzi dvoma službami.

    Component testing rieši vnútornú logiku jednej služby, napríklad spracovanie vstupu. Contract testing sa touto logikou nezaoberá, zaujíma ho len to, čo služba posiela von. Rovnaká funkcia môže prejsť component testami, a napriek tomu porušiť kontrakt zmenou formátu JSON objektu.

    Consumer-driven contract testing: princíp

    Pri consumer-driven prístupe consumer služba ako prvá napíše, čo od provider API očakáva. Provider potom svoju implementáciu overuje práve voči tomuto očakávaniu.

    Tento smer nie je náhodný: consumer najlepšie vie, aké dáta a v akom tvare potrebuje, keďže ich priamo spracúva. Kontrakt tak vzniká z jeho reálnych požiadaviek, nie z odhadu provider tímu.

    Skratka CDC (consumer-driven contract) sa v tíme často používa samostatne. CDC prístup je pri mikroslužbách bežnejší než provider-driven, pretože pri desiatkach consumer služieb je nepraktické manuálne dohadovať kontrakt pre každú z nich.

    Existuje aj opačný smer, provider-driven contract testing, kde kontrakt definuje provider. Hodí sa pri malom počte consumerov, inak je ťažké udržať prehľad, preto je v praxi menej bežný.

    16 min.Tester pracuje s API requestmi, dokumentáciou a architektúrou systému na dvoch monitoroch.

    API testing: Čo to je, ako funguje a aké nástroje použiť

    API testing je efektívny spôsob, ako odhaliť chyby skôr, než sa dostanú k používateľovi. Zoznám sa s typmi API testov a nástrojmi pre testerov.

    Pact: referenčný nástroj pre contract testing

    Pact je open-source nástroj, ktorý je de facto štandardom pre consumer-driven contract testing a podporuje väčšinu bežných jazykov a frameworkov.

    Pracuje s kontraktmi vo forme JSON súborov, tzv. pactov, ktoré vznikajú automaticky pri consumer testoch. Test nevolá reálny provider server, ale beží proti mock serveru. Tieto pacty potom provider tím použije na verifikáciu voči skutočnému API. Pact podporuje Java, JavaScript aj .NET.

    Pre tímy s hotovou OpenAPI špecifikáciou existuje alternatíva: OpenAPI contract testing overuje kontrakt priamo voči nej. Spring Cloud Contract testing zase sedí Spring a Java ekosystému. Komerčná nadstavba Pactflow pridáva vizualizáciu kontraktov a správu verzií pre väčšie tímy.

    Nasledujúci konceptuálny príklad ukazuje, ako vyzerá jednoduchý Pact consumer test v JavaScripte:

    // Pact consumer test (JavaScript, koncept)
    const provider = new Pact({ consumer: "WebApp", provider: "UserService" });
    
    provider.addInteraction({
      state: "user 123 existuje",
      uponReceiving: "request na detail používateľa",
      withRequest: { method: "GET", path: "/users/123" },
      willRespondWith: {
        status: 200,
        body: { id: 123, name: like("Ján Novák") }
      }
    });
    

    Pact Broker: na čo slúži

    Pact Broker je centrálne úložisko kontraktov, ktoré consumer aj provider tímy zdieľajú a kde broker automaticky overí, či nová verzia API neporušuje existujúci kontrakt.

    Vždy, keď consumer alebo provider zmení verziu, publikuje nový pact do brokera, ktorý uchováva históriu všetkých verzií a vzťahov medzi službami.

    Kľúčový mechanizmus sa volá can-i-deploy: pred nasadením broker skontroluje, či nová verzia neporuší kontrakt existujúcich consumerov alebo providerov, a dá jasnú odpoveď áno alebo nie.

    Broker eviduje aj tagy a prostredia, takže vieš rozlíšiť, ktorá verzia kontraktu platí pre produkciu a ktorá pre staging.

    Vieš, že…

    … contract test spustíš aj lokálne bez bežiacej druhej služby, takže nesúlad formátu odhalíš ešte pred prvým integračným testom?

    Contract testing a CI/CD

    Contract testy nasadíš do CI/CD pipeline pred každým deployom. Broker overí can-i-deploy stav skôr, než sa nová verzia dostane do produkcie.

    Typický flow: consumer tím spustí testy a vygeneruje pact, publikuje ho do brokera, provider spustí verifikáciu a výsledok sa zapíše späť. Až keď can-i-deploy vráti pozitívnu odpoveď, pipeline pokračuje k nasadeniu.

    Vďaka tomuto gate sa problém so zhodou formátu odhalí ešte pred produkciou, nie až keď zákazník narazí na chybu. Contract testing sa tak stáva rýchlym a lacným poistným ventilom v mikroslužbovej architektúre.

    11 min.Continuous Integration, delivery, CI CD pipepline, testing tools

    Continuous Integration, continuous delivery a CI CD pipeline v testingu

    V článku sa dozvieš, čo je Continuous Integration, delivery a CI CD pipeline v testingu, ako ho automatizovať a aké nástroje sú na to najlepšie.

    Kedy contract testing nasadiť (a kedy nie)

    Contract testing má zmysel, keď máš aspoň dve nezávisle nasadzované služby, ktoré medzi sebou komunikujú cez API. Pri monolite alebo jednej izolovanej službe ho nepotrebuješ.

    Pri rozhodovaní pomôže jednoduché kritérium: ak sa API rozhranie mení často a služby nasadzujú rôzne tímy nezávisle, contract testing sa ti oplatí. Pri jednej aplikácii s jednou databázou by bol zbytočnou réžiou navyše.

    Ak už robíš API testing napríklad cez Postman, contract testing je logický ďalší krok pri raste počtu mikroslužieb.

    Zavedenie contract testingu si vyžaduje počiatočnú investíciu do brokera a CI kroku, preto sa oplatí, keď počet služieb a tímov rastie.

    Recommend

    Odporúčame ti…

    Pri prvom nasadení contract testingu začni s jedným kritickým consumer-provider párom, nie s celou mikroslužbovou mriežkou naraz. Overíš si proces skôr, než ho škáluješ.

    FAQ: Často kladené otázky o contract testing

    Čo je contract testing?

    Contract testing je metóda, ktorá overuje, či si consumer a provider služba rozumejú cez zdieľaný kontrakt o formáte komunikácie. Kontrakt je JSON alebo YAML dokument s očakávanými requestmi a responses. Na rozdiel od klasického API testingu neoveruje funkčnosť, len formát. Beží nezávisle na oboch stranách, pretože každá služba sa testuje voči zapísanému kontraktu, nie voči bežiacej druhej službe.

    Je contract testing to isté ako API testing?

    Nie. API testing overuje funkčnosť celého API, contract testing len zhodu formátu medzi consumer a provider. API testing zahŕňa aj business logiku, kým contract testing rieši len štruktúru dát. Je preto podmnožinou API testingu, nie jeho náhradou. Contract testy zachytia rozbitý formát skoro a lacno, správanie endpointov potom preveria API testy.

    Aký je rozdiel medzi contract testingom a integration testingom?

    Integration testing potrebuje bežiace prostredie oboch služieb, contract testing beží izolovane bez neho. Integration testing je preto pomalší a krehkejší, závisí od infraštruktúry aj siete. Contract testing je rýchlejší a spustíš ho aj lokálne, lebo mu namiesto druhej služby stačí zapísaný kontrakt. Oba typy sa dopĺňajú, nenahrádzajú sa: contract testy overia formát komunikácie, integračné testy to, či služby spolu naozaj fungujú.

    Aký je rozdiel medzi contract testingom a component testingom?

    Component testing overuje jednu službu izolovane, contract testing sa zameriava na rozhranie medzi dvoma službami. Component testing rieši vnútornú logiku služby, napríklad spracovanie vstupu. Contract testing rieši len formát requestov a responses medzi službami. Služba preto môže kontrakt dodržať a napriek tomu vrátiť nesprávne vypočítanú hodnotu, čo odhalí až component test.

    Čo je Pact Broker a na čo slúži?

    Pact Broker je centrálne úložisko kontraktov, ktoré automaticky overí, či je bezpečné nasadiť novú verziu API. Zdieľajú ho consumer aj provider tímy a uchováva históriu pactov. Kľúčový je mechanizmus can-i-deploy, ktorý pred nasadením odpovie, či nová verzia neporuší kontrakt inej služby. V CI/CD pipeline tak funguje ako brána, cez ktorú prejde len kompatibilná verzia.

    Musím pri contract testingu použiť práve Pact?

    Nie. Pact je najrozšírenejší nástroj s najväčšou komunitou, no existujú aj alternatívy ako OpenAPI-based contract testing alebo Spring Cloud Contract. OpenAPI-based prístup sedí tímom, ktoré už majú hotovú OpenAPI špecifikáciu a chcú kontrakt overovať priamo voči nej. Spring Cloud Contract je prirodzená voľba v Spring a Java ekosystéme. Rozhoduje teda najmä to, s akými technológiami tím už pracuje.

    Contract testing: Kedy dáva zmysel začať

    Contract testing dáva najväčší zmysel, keď tvoj systém rastie za hranicu jednej alebo dvoch služieb a API medzi nimi sa mení často. Zhodu formátu overíš rýchlo a izolovane, ešte pred pomalšími integračnými testami.

    Nástroj Pact spolu s Pact Broker a mechanizmom can-i-deploy pokrýva väčšinu bežných scenárov. Začni s jedným kritickým párom, over si proces, a až potom ho škáluj na zvyšok systému.

    O autorovi

    Katarína Kučáková

    Software Test Engineer

    Moja cesta k testovaniu softvéru sa začala v roku 2019 až po štúdiu ekonómie a pracovných skúsenostiach v iných odvetviach. To mi pomohlo vnímať IT svet v rôznych súvislostiach. Ten totiž ponúka neustále nové výzvy, pre ktoré rada hľadám riešenia. Obľubujem oddych pri čítaní, turistiku alebo lyžovanie. LinkedIn

    Daj nám o sebe vedieť