Testovací strategie a audit

Unit, integrační a end-to-end testy: jaký je rozdíl

Unit, integrační a end-to-end test se neliší tím, který je „lepší“, ale především šířkou hranice a skutečnými částmi zapojenými do běhu. Čím je test užší, tím bývá zpětná vazba rychlejší a chyba se snáze lokalizuje; čím je širší, tím více reálných propojení může potvrdit, ale tím více příčin může mít selhání. Přesné rozlišení pomáhá rozdělit kontroly bez slepých míst a bez nákladného opakování stejných kombinací na každé úrovni.

Proč se názvy v týmech rozcházejí

„Unit“ nemusí znamenat jednu metodu a „integrační“ nemusí znamenat celý systém. Pro jeden tým je test služby s reálnou databází integrační; jiný jej nazývá komponentovým a označení integrace si nechává pro komunikaci mezi dvěma službami. Ani uživatelské rozhraní (UI) a end-to-end (E2E) nejsou synonyma: UI lze testovat izolovaně a celý koncový tok lze spustit přes API.

Také Practical Test Pyramid upozorňuje, že názvy vrstev nejsou univerzální a že konzistentní definice v týmu je důležitější než spor o jediný slovník. Proto se u každého typu ptejte na tři konkrétní věci:

  1. Co je předmětem testu a kudy do něj test vstupuje?
  2. Které spolupracující části jsou reálné a které nahrazené?
  3. Jaký pozorovatelný výsledek test potvrzuje?

Takový popis odhalí skutečný rozsah i tehdy, když dva týmy používají stejný název odlišně. V širší taxonomii jde o osu úrovně; druhy testování softwaru lze současně třídit také podle cíle, způsobu a doby spuštění.

Jeden e-shop, pět možných hranic

Použijme realistický příklad. E-shop má kalkulačku ceny, která pracuje s cenou položky, DPH, množstvím a kupónem. Komponenta košíku tato pravidla používá a připraví požadavek. Objednávková služba přes API uloží objednávku do databáze, požádá sklad o rezervaci a platební bránu o vytvoření platby. Webové UI umožní zákazníkovi projít checkoutem.

Požadavek říká: kupón LETO10 sníží cenu způsobilých položek o 10 %, sleva se uplatní před výpočtem DPH a výsledná částka se zaokrouhlí podle dohodnutého pravidla. Po úspěšném odeslání musí vzniknout objednávka se stejnou částkou, sklad musí rezervovat množství a zákazník se má dostat k platbě.

Jeden požadavek tak vytváří několik odlišných otázek. Počítá pravidlo všechny hraniční případy? Používá košík pravidlo správně? Zapíše databázový adaptér přesnou částku? Rozumějí si objednávka a sklad? Dokáže zákazník dokončit cestu v nasazeném systému? Každá otázka má přirozenou testovací hranici.

Unit test: malé chování v kontrolovaných podmínkách

Unit neboli jednotkový test ověřuje malou jednotku chování bez skutečné sítě, databáze, fronty zpráv nebo jiného pomalého či nedeterministického vnějšího systému. Jednotkou může být funkce, třída nebo malá skupina úzce souvisejících objektů. Hranice není dána počtem řádků kódu, ale tím, co tým považuje za jedno ucelené chování.

V našem příkladu zavolá test kalkulačku s cenou 100 eur, způsobilým kupónem a konkrétní sazbou DPH. Ověří přesný mezisoučet, daň a konečnou cenu. Další případy pokryjí neplatný kupón, nulové množství, hranici platnosti a zaokrouhlování. Hodiny lze nahradit řízeným zdrojem času, aby test nezávisel na dnešním datu.

Unit test má říci, že pravidlo je nesprávné, nikoli že se nepodařilo spustit databázi. Proto bývá rychlý, opakovatelný a vhodný pro mnoho kombinací. Stejně důležitý je jeho limit: neověřuje mapování JSON, databázový typ částky, konfiguraci DPH ani to, zda UI posílá kupón do správného pole.

Testujte pozorovatelné chování přes veřejnou hranici jednotky. Pokud test předepisuje pořadí každého interního volání, může jej neškodná refaktorizace rozbít, aniž se změní výsledek pro uživatele.

Komponentový test: celý modul, ne celý ekosystém

Komponentový test spustí větší celek a přistupuje k němu přes jeho veřejné rozhraní. U frontendového košíku může vykreslit celou komponentu, zadat kupón a ověřit zobrazenou částku, zatímco objednávkové API nahradí řízenou odpovědí. U backendové služby může spustit aplikaci přes HTTP se skutečnou interní logikou, ale sklad a platbu ponechat jako simulace.

Tato vrstva odhaluje chyby v propojení vnitřních částí komponenty: formulář sice načte kupón, ale stav nepředá kalkulačce; nebo controller nesprávně mapuje požadavek do doménového modelu. Zůstává užší než test celého nasazeného produktu, takže ji lze připravit cíleněji a selhání má menší okruh příčin.

Slovo komponenta je třeba v projektu definovat. Může znamenat vizuální prvek, balíček i samostatně nasaditelnou službu. Bez uvedení hranice název sám neříká, jakou jistotu test poskytuje.

Integrační test: důkaz na skutečné hranici

Integrační test ověřuje, že si dvě nebo více reálných částí správně předají data a chování. Úzký integrační test může zapojit objednávkovou službu a databázi: po volání repozitáře ověří částku, měnu, položky a stav uložený ve skutečné podporované databázi. Jiný spojí producenta a reálný message broker, aby prověřil název tématu, serializaci a potvrzení zprávy.

Širší integrační test může spustit objednávku i testovací instanci skladu. Ověří, že požadavek na rezervaci obsahuje správné identifikátory a že odpověď „nedostatek zásob“ přejde do správného stavu objednávky. Pokud místo skladu použije simulaci, testuje reálné HTTP chování objednávkové služby, nikoli kompatibilitu s aktuální implementací skladu.

Právě proto je třeba zapsat reálné závislosti. Databáze jiného typu, než používá produkce, může být vhodná pro část rychlých kontrol, ale nemusí odhalit rozdíly v typech, transakcích nebo SQL. Naopak spuštění každé vzdálené služby v každém testu prodraží přípravu a zvýší počet nesouvisejících selhání.

Na hranicích API doplňuje integrační testy kontraktní testování. Kontrakt ověřuje zaznamenaná očekávání klienta a poskytovatele i bez společného běhu celého systému. Nenahrazuje však test síťové konfigurace, autentizace ani reálných vedlejších účinků.

Systémový a E2E test: celek a koncová cesta

Systémový test ověřuje sestavený produkt jako celek vůči požadavku. Může vést přes veřejné API nebo UI a nemusí procházet jinými organizacemi či externími systémy. E2E test sleduje ucelený obchodní nebo uživatelský tok přes relevantní hranice od spouštěče po konečný výsledek.

V e-shopu může E2E scénář vytvořit produkt a kupón, otevřít checkout, odeslat objednávku, projít testovací platbou a ověřit stav objednávky i rezervaci skladu. Pokud platební brána neposkytuje bezpečný sandbox, může ji tým v kontrolovaném prostředí nahradit. Test pak stále prochází koncovou cestou ve vlastním systému, ale nepotvrzuje reálnou integraci s bránou; tu je třeba pokrýt samostatným testem v povolených podmínkách.

E2E poskytuje důkaz, že vybraná cesta drží pohromadě, ale selhání může způsobit UI, API, data, síť, sklad, platba nebo prostředí. Proto přes něj neprocházejte každou kombinaci kupónu. Jedna či několik reprezentativních cest potvrdí propojení, zatímco hraniční ceny patří níže. Praktický návrh nákupních cest rozebírá automatizované testování e-shopu.

Akceptační test není další synonymum. Říká, zda je splněna podmínka přijetí; podle toho, kde vznikne dostatečný důkaz, může být unit, komponentový, API i E2E.

Test doubles, stuby, fake objekty a mocky

Test double je zastřešující název pro náhradu produkční závislosti v testu. Terminologie knihoven se liší, ale užitečné je rozumět úloze náhrady:

Náhrady dávají testu kontrolu nad chybami, časem a okrajovými stavy. Současně vytvářejí riziko: test může dokazovat pouze to, že kód spolupracuje s naší představou cizí služby. Čím důležitější je hranice, tím více je třeba simulaci doplnit kontraktem nebo úzkým testem se skutečnou implementací. Mockujte především vnější hranici a nestavte celý test na ověřování interních volání, která uživatel nepozoruje.

Porovnání bez falešné hierarchie

Typ Typická hranice Reálné závislosti Silná stránka Hlavní limit
Unit malé pravidlo nebo objekt zpravidla bez sítě a databáze rychlé kombinace, přesná diagnóza nepotvrdí propojení
Komponenta modul, UI komponenta nebo služba vnitřek reálný, okolí často nahrazené chování celku přes veřejnou hranici pojem potřebuje místní definici
Integrace jedna nebo více technických hranic vybrané sousední části reálné schémata, protokoly, databáze, konfigurace náročnější příprava a izolace
Systém sestavený produkt většina vlastních částí reálná požadavky na chování celku širší okruh příčin selhání
E2E celá vybraná cesta relevantní řetězec podle deklarovaného rozsahu důvěra v kritický tok pomalejší běh, data a diagnostika

Tabulka neurčuje pořadí důležitosti. Unit test nezastoupí integraci a E2E test nenahradí přesné pokrytí pravidla. Každý odpovídá na jinou otázku.

Jak zvolit úroveň pro konkrétní riziko

Nejprve napište tvrzení, které má test dokázat. Potom zvolte nejnižší hranici, na níž je toto tvrzení stále pravdivé:

Potom odstraňte zbytečné opakování. Pokud dvacet kombinací ceny spolehlivě ověřují unit testy, E2E stačí pro reprezentativní cenu a správný přenos výsledku. Neodstraňujte však kontrolu hranice jen proto, že je pravidlo pokryté níže.

Testovací pyramida je zde užitečná jako směřování k více úzkým a menšímu počtu širokých testů, nikoli jako povinný poměr. Produkt s množstvím vlastní logiky bude mít jiné rozložení než integrační aplikace nad cizími službami. Rozhodujte podle architektury, následku chyby, rychlosti zpětné vazby a ceny údržby.

Na co si dát pozor v reálné sadě

Mnoho mocků může vytvořit rychlou zelenou sadu, která nevidí chybné schéma ani konfiguraci. Mnoho širokých testů zase prodlouží běh a při společných datech způsobí nestabilitu. Test, který projde jen v určitém pořadí, neposkytuje spolehlivý důkaz; pomáhá, když si scénář připraví vlastní nezávislá testovací data a po sobě je kontrolovaně uklidí.

Pozor také na nejasný report. Název „checkout works“ neřekne, zda selhal výpočet, HTTP kontrakt nebo zobrazení. Zachovejte viditelnou hranici testu, vstup, očekávání a diagnostické údaje. Když širší test selže, mají úzké testy pomoci zúžit příčinu, nikoli pouze zopakovat stejný scénář jiným nástrojem.

Rozdělení běhů přizpůsobte zpětné vazbě. Rychlé unit a komponentové testy mohou běžet při každé změně, vybrané integrace podle dotčené oblasti a malá kritická E2E sada po nasazení. Širší regresi lze spustit v další fázi; konkrétní možnosti shrnuje článek o automatizovaných testech v CI/CD.

Co vhodné rozložení přinese

Vrstvená sada dává týmu rychlou informaci o chybném pravidle i samostatný důkaz, že klíčové hranice fungují. Snižuje potřebu procházet každou kombinaci přes drahou koncovou cestu a zároveň nepředstírá, že izolované mocky potvrdily reálné nasazení. Při selhání se snáze určí vlastník a při změně architektury je vidět, které hranice je třeba přehodnotit.

Další krok

Vyberte deset kritických scénářů a u každého vypište jednotlivá tvrzení, která dnes testujete. Ke každému doplňte hranici, reálné závislosti, použité test doubles, dobu běhu a typické příčiny selhání. Označte tvrzení, která se zbytečně opakují v E2E, i hranice, které nejsou reálně ověřené nikde. Následně přesuňte jednu skupinu kombinací na užší úroveň a ponechte jeden reprezentativní koncový scénář jako důkaz celého toku.

Související témata

Mohlo by vás také zajímat

Ujasníme si, kde má automatizace největší očekávaný přínos

Posoudíme váš testovací proces a navrhneme, co automatizovat, co ponechat ručně a čím začít.