API testy

Jak testovat webhooky: podpis, duplicity, pořadí a zpožděné doručení

Webhook je požadavek, kterým externí služba oznámí vaší aplikaci událost: dopravce změnil stav zásilky, fakturační systém vystavil doklad nebo CRM upravilo kontakt. Jeden úspěšný požadavek v Postmanu ale nepotvrdí, že integrace zvládne skutečný způsob doručování. Tento postup pomůže vývojovému a QA týmu ověřit podpis, opakování, pořadí i zpoždění, aniž by z funkčního testu dělal bezpečnostní audit.

Proč nestačí dostat odpověď 200

Webhook spojuje dvě samostatné věci. Nejprve musí endpoint přijmout a ověřit HTTP požadavek. Potom musí aplikace změnit správný obchodní stav, například označit zásilku jako doručenou, vytvořit fakturu nebo zařadit kontakt do kampaně.

Pokud test zkontroluje jen stavový kód, může přehlédnout, že se událost uložila dvakrát, starší stav přepsal novější nebo se vedlejší účinek provedl ještě před bezpečným uložením zprávy. Naopak správná změna v databázi ještě nedokazuje, že endpoint odmítne požadavek s neplatným podpisem. Testovací model proto musí sledovat přijetí, zpracování i výsledek.

Modelová situace: zásilka se vrátila do staršího stavu

Představte si e-shop, který po události „zásilka doručena“ označí objednávku za dokončenou a odešle zákazníkovi e-mail. Endpoint událost přijme a uloží, jeho odpověď se ale kvůli síťovému timeoutu nedostane k dopravci. Dopravce proto tutéž událost pošle znovu. Pokud dva zpracovatelské procesy začnou obě kopie zpracovávat souběžně bez společné ochrany, mohou odeslat dva e-maily nebo dvakrát zapsat odměnu do věrnostního programu.

O několik minut později přijde starší událost „zásilka na cestě“, která se zpozdila ve frontě. Kód, jenž jednoduše přepíše stav hodnotou z poslední přijaté zprávy, vrátí dokončenou objednávku zpět. Každý jednotlivý požadavek přitom může skončit odpovědí 200 a v technickém logu vypadat úspěšně.

Správným výsledkem modelového testu není konkrétní implementace, ale pozorovatelná pravidla: konečný stav zůstane „doručena“, zákaznický e-mail vznikne jednou, obě doručení lze dohledat a neznámý nebo starší vstup nezpůsobí nepovolený přechod. Takto formulovaná očekávání zůstávají užitečná také tehdy, když tým později vymění databázi nebo frontu zpráv.

Nejprve si zapište kontrakt poskytovatele

Jeden univerzální webhookový protokol neexistuje. Poskytovatelé používají různé hlavičky, algoritmy podpisu, identifikátory událostí, pravidla opakování i očekávané odpovědi. Před tvorbou scénářů si z oficiální dokumentace poznamenejte:

Například Stripe dokumentuje původní tělo požadavku, automatická opakování, duplicity i negarantované pořadí. Jde o kontrakt konkrétního poskytovatele, ne o pravidlo, které lze bez kontroly přenést na dopravce nebo CRM.

Kontrakt převeďte do malé rozhodovací tabulky. Pro každý typ události uveďte povinná pole, objekt, který se má najít, povolený výchozí stav, nový stav a vedlejší účinky. Samostatně určete chování pro neznámý typ, neznámý objekt a platně podepsanou, ale neúplnou zprávu. Endpoint může zprávu technicky přijmout, ale označit ji za nezpracovanou a poslat ji do řízené chybové fronty. Tým potom nezaměňuje „HTTP požadavek přijat“ za „obchodní změna dokončena“.

Scénáře, které odhalí nejvíce chyb

1. Ověřte podpis nad původním tělem

Připravte platnou událost podle testovacích údajů poskytovatele a potom samostatně změňte tělo, podpis, hlavičku a použité tajemství. Platný požadavek má pokračovat ke zpracování, neplatný se nesmí projevit v obchodních datech.

Podpis se často počítá z přesného těla přijatého požadavku. Pokud framework nejprve JSON rozbalí a znovu sestaví, může změnit mezery, pořadí nebo kódování a ověření selže. Stripe proto vyžaduje raw body; GitHub ve svém postupu také počítá HMAC, tedy ověřovací kód vytvořený z tajemství a původního těla, a porovnává jej s podpisem v hlavičce. Testujte algoritmus, hlavičku, kódování a případnou časovou toleranci přesně podle zvoleného poskytovatele.

2. Pošlete stejnou událost vícekrát

Doručte tutéž zprávu dvakrát po sobě a potom také souběžně. Neověřujte pouze počet řádků v tabulce událostí. Zkontrolujte každý vedlejší účinek: faktura, e-mail, skladový pohyb nebo změna stavu mají vzniknout podle obchodního pravidla, ne znovu při každém přijetí.

Idempotentní zpracování znamená, že opakování stejné události nevytvoří druhý obchodní výsledek. Obvykle pomůže evidence již zpracovaného identifikátoru s databázovým omezením, které funguje i při souběhu. Dvě různé události o stejném objektu však nemusí být technickou duplicitou, proto je nutné kontrolovat také povolený přechod obchodního stavu.

3. Změňte pořadí jen tam, kde to kontrakt připouští

Pokud poskytovatel pořadí negarantuje, pošlete novější stav před starším. Aplikace nemá zásilku po doručení vrátit do stavu „odeslána“ jen proto, že později přijala starší zprávu. Řešením může být verze události, čas z důvěryhodného zdroje, pravidla stavového automatu nebo načtení aktuálního objektu přes API poskytovatele. Správnou volbu určuje jeho kontrakt a vaše obchodní pravidla.

4. Simulujte zpoždění, timeout a opakování

Odložte událost o minuty či hodiny a ověřte, zda ji aplikace stále zpracuje do konzistentního stavu. Potom nasimulujte timeout nebo chybu endpointu a použijte mechanismus opětovného doručení, který nabízí sandbox, administrace nebo příkazový nástroj (CLI) poskytovatele. Nespoléhejte na vlastní odhad jeho harmonogramu opakování.

Samostatně testujte hranici mezi přijetím a zpracováním. Pokud endpoint nejprve uloží zprávu do fronty a rychle odpoví podle kontraktu, vyzkoušejte pád před uložením, po uložení i během zpracování. Cílem je, aby potvrzená událost nezmizela a opakovaná událost neprovedla účinek dvakrát.

5. Kontrolujte výsledek a diagnostiku

Ke každému vstupu přiřaďte očekávanou HTTP odpověď, záznam události, konečný obchodní stav a povolené vedlejší účinky. V logu používejte identifikátor doručení nebo události, aby tým dokázal spojit požadavek se zpracováním. Citlivá pole a celá těla ale neukládejte automaticky; diagnostika musí respektovat pravidla pro osobní a přístupové údaje.

Jak uzavřít test důkazem, ne pouze čekáním

Asynchronní zpracování nemusí skončit v okamžiku HTTP odpovědi. Test proto po odeslání webhooku nemá používat náhodně dlouhou pauzu. Má čekat s pevným časovým limitem na pozorovatelný výsledek: záznam se stavem „zpracováno“, očekávanou změnu přes API nebo zprávu v testovacím výstupu fronty. Po překročení limitu uloží mezistavy a skončí neúspěšně; nemá čekat bez omezení.

Pro každý scénář ověřte čtyři úrovně:

  1. Přijetí: stavový kód a rozhodnutí o platnosti podpisu.
  2. Evidence: identifikátor události, počet pokusů a stav zpracování.
  3. Obchodní výsledek: správný objekt, konečný stav a hodnoty, které se měly změnit.
  4. Negativní důkaz: nevznikla druhá faktura, druhý e-mail ani zpětný přechod.

Při souběžném testu odešlete kopie zároveň pomocí mechanismu, který uvolní oba požadavky ve stejném okamžiku, ne rychle po sobě v jedné smyčce. Potom počkejte na dokončení obou pokusů a zkontrolujte databázové omezení i obchodní výsledek. Nakonec spusťte také proces sesouhlasení stavu, pokud jej systém používá: jeho úlohou může být dohledat u poskytovatele aktuální stav po ztracené nebo neúplné události. Samostatný test tak ověří nejen běžné doručení, ale i cestu návratu ke konzistentním datům.

Kombinujte tři testovací vrstvy

Lokální test s řízenou zprávou rychle pokryje neplatný podpis, souběh a chybové větve. Sandbox poskytovatele ověří skutečný formát, hlavičky a podporované opakování. Malý integrační scénář pak potvrdí celý tok až po obchodní výsledek. Rozdíly mezi těmito vrstvami vysvětluje článek Mock, sandbox nebo reálná služba.

Test podpisu dokazuje funkci implementace v pokrytém kontraktu. Není posouzením celkové bezpečnosti endpointu, správy tajemství, sítě ani oprávnění. Stejně tak úspěšný sandboxový scénář nepotvrzuje rychlost a dostupnost produkčního poskytovatele.

Co tím získáte

Taková sada odhalí chyby, které šťastná cesta neukáže: dvojitou fakturu, zpětný přechod stavu, ztracenou událost nebo neplatnou zprávu přijatou ke zpracování. Tým zároveň dostane opakovatelný důkaz, jaké chování integrace zvládá a pro který kontrakt.

Další krok

Vyberte jeden webhook se skutečným obchodním účinkem a vytvořte matici pěti vstupů: platný, neplatně podepsaný, duplicitní, zpožděný a doručený v jiném pořadí, pokud je poskytovatel negarantuje. Ke každému doplňte očekávanou odpověď, stav a vedlejší účinky. Teprve potom scénáře zapojte do automatizovaných API testů.

Související témata

Mohlo by vás také zajímat

Chyby v obchodní logice odhalíte rychleji přímo přes API

Funkční, integrační a kontraktní testování REST, SOAP či GraphQL rozhraní s možností zapojení do CI/CD pipeline.