Slovník pojmů
Integrační test
Integrační test kontroluje skutečné napojení na vybranou infrastrukturu. Nemusí a nemá volat produkční cizí službu, aby byl užitečný.
Stručná definice
Skutečné propojení vybraných částí v kontrolovaném prostředí.
Integrační test může ověřit SQL dotaz proti testovací databázi, ukládání do Redis nebo převod HTTP odpovědi v adapteru. Části jsou skutečné, ale prostředí je vyhrazené pro test a jeho data mají řízený životní cyklus.
Není to unit test, který izoluje pravidlo pomocí doubles. Není to ani E2E test přes prohlížeč, pro který se často používá Playwright. Contract test zase ověřuje sdílený kontrakt mezi poskytovatelem a klientem; integrační test může odhalit více lokálních detailů, ale sám negarantuje kompatibilitu se všemi cizími verzemi.
Jaký problém řeší
Chyby, které double neumí věrně nahradit
Smyslem není spustit všechno najednou, ale vybrat technickou hranici s významným rizikem.
- mapování entity, constrainty a transakci nad skutečnou testovací databází
- serializaci, hlavičky a chybové stavy HTTP adapteru proti řízenému test serveru
- TTL, klíče a invalidaci nad samostatným Redisem
- konfiguraci PHP aplikace a závislostí v Docker kontejneru
- zpracování fixture a následný cleanup bez sdílení dat s jiným během
Praktický příklad
Repository uloží a načte objednávku z testovací databáze
Test spustí skutečný databázový adapter proti databázi určené jen pro testy. Nepracuje s produkčním připojením a po scénáři vrátí transakci nebo uklidí data. Tím zachytí chybu v SQL, schématu nebo mapování, kterou paměťový fake odhalit nemusí.
Nezávislost je důležitá i při paralelním běhu. Každý test potřebuje vlastní data, transakci, databázi nebo bezpečně oddělený namespace. Fixture mají vytvářet nejmenší možný výchozí stav, ne kopii produkčních osobních dat.
PHP
final class OrderRepositoryTest extends TestCase
{
public function testItPersistsAndLoadsOrder(): void
{
$order = Order::create('order-123');
$this->repository->save($order);
$loadedOrder = $this->repository->get('order-123');
self::assertSame('order-123', $loadedOrder->id());
}
}
Diagram rozsahu
Od pravidla k adapteru a uživatelskému scénáři
Diagram: unit test = izolované pravidlo; integrační test = skutečný adapter a testovací služba; E2E = celý scénář v rozhraní.
- Unit test Řídí vstupy přes stub, mock nebo fake a rychle ověří pravidlo bez sítě, databáze a containeru.
- Integrační fixture Test nastaví malé údaje v testovací databázi, Redis namespace nebo lokálním HTTP test serveru.
- Skutečná hranice Aplikace volá konkrétní driver či adapter. Test ověří SQL, serializaci, cache, konfiguraci nebo mapování.
- Cleanup a izolace Po testu se data vrátí transakcí, smažou nebo se zruší kontejner. Další test nesmí záviset na jejich pořadí.
- E2E a contract test E2E ověřuje uživatelský tok přes rozhraní. Contract test drží sdílenou dohodu klienta a poskytovatele; ani jeden není automatickou náhradou integrace.
Nástroje a hranice
Test runner není hranice testu.
PHPUnit může spustit unit i integrační test. Rozhoduje, zda test volá skutečnou technologickou část.
PHPUnit
Zajišťuje test runner, assertions a lifecycle fixture. Testovací databázi ani cleanup za projekt automaticky nenavrhne.
Docker
Může poskytnout reprodukovatelnou testovací službu, ale nesmí omylem připojit test na sdílený volume nebo produkční proměnné.
Playwright
Browserový E2E nástroj. Může stát nad integračními vrstvami, ale testuje širší uživatelskou hranici.
Důležité pojmy
Skutečná infrastruktura ano, neřízené produkční okolí ne.
Dobrá integrační sada míří na konkrétní hranice a ví, jak po sobě uklidit.
Testovací databáze
Má vlastní URL, uživatele a data. Transakce může urychlit cleanup, ale musí odpovídat tomu, co adapter skutečně dělá.
Redis a fronta
Použij vyhrazený Redis či namespace a po testu klíče ukliď. Cache ani fronta nesmí sdílet stav s lokálním vývojem nebo produkcí.
HTTP adapter
Testuj request, hlavičky, timeout a převod odpovědi proti lokálnímu test serveru, stub serveru nebo zaznamenanému scénáři. Produkční externí API není povinná testovací závislost.
Kontejner
Docker může dodat verzi databáze či brokeru podobnou provozu. Obraz služby, porty, readiness a cleanup jsou součástí testovacího návrhu.
Fixture a cleanup
Fixture vytváří nezbytný stav; cleanup jej po testu odstraní. Test, který funguje jen po jiném testu, není izolovaný.
Výhody a omezení
Vyšší důvěra ve spojení za cenu času a infrastruktury.
Přínosy
- odhalí chybu SQL, konfigurace, serializace či skutečného driveru
- ověří migraci, constraint nebo cache chování v reálnější podobě
- dává důvěru adapteru bez volání produkční externí služby
- může chránit kritickou integrační hranici před regresí
Na co pozor
- testy jsou pomalejší než unit testy a potřebují lifecycle infrastruktury
- sdílená data, porty nebo cache namespace vedou k flaky výsledkům
- produkční API je nevhodné pro běžný automatický test kvůli ceně, datům a dostupnosti
- integrační test sám neověří celý uživatelský scénář ani sdílený contract dodavatele
Kdy dává smysl
Když riziko leží na rozhraní mezi aplikací a technologií.
Integrační test patří tam, kde je důležité, že konkrétní SQL, ORM mapping, Redis klient, HTTP adapter nebo kontejnerová konfigurace opravdu fungují. Ne každý getter potřebuje vlastní infrastrukturu; vybírej hranice s historií chyb nebo výrazným dopadem.
Většinu scénářů nechej rychlým unit testům. Menší sada integrací nad řízenými službami doplní chybějící jistotu. E2E testy potom nech pro několik kritických toků, které opravdu potřebují prohlížeč a celé rozhraní.
Na co myslet
Infrastruktura testu je součást testovaného kontraktu.
Pomalý nebo nespolehlivý integrační test není nutná daň; často ukazuje nejasnou izolaci či lifecycle.
- oddělit testovací připojení a credentials od vývoje i produkce
- čekat na readiness služby místo pevného sleep
- vytvářet malé fixture a po testu provést rollback, smazání či zrušení namespace
- nepouštět testy nad produkčním externím API; použít test server, sandbox nebo contract scénář
- pojmenovat porty, kontejnery a klíče tak, aby paralelní běhy nekolidovaly
- řadit integrační testy do CI/CD podle rizika a dávat jim srozumitelný výstup při selhání
Časté otázky
Integrační test bez záměn
Musí integrační test volat produkční externí API?
Ne. Běžně je lepší lokální test server, dodavatelský sandbox nebo kontrolovaný contract scénář. Produkční API je nestabilní, může stát peníze a pracovat s citlivými daty.
Je test s PHPUnitem automaticky unit test?
Ne. PHPUnit je runner. Pokud test používá skutečnou databázi, Redis nebo HTTP adapter, jde podle rozsahu o integrační test.
Je integrační test E2E test?
Ne. Integrační test míří na vybranou technickou hranici. E2E test projde celou aplikaci z pohledu uživatele, často přes prohlížeč.
Je contract test totéž?
Ne. Contract test ověřuje dohodnutý formát a očekávání mezi systémy. Integrační test ověřuje konkrétní spolupráci implementací v testovacím prostředí.
Jak držím kvalitu vývoje
Technické hranice ověřuji skutečnou službou, ale v kontrolovaném prostředí.
U PHP aplikací kombinuji testovací databáze, kontejnery a quality gates tak, aby integrace dávaly důvěru bez rizika pro provozní data.