Testovací pyramida, o které většina týmů omylem zapomíná
Při návrhu testů platí jednoduché pravidlo: nejdříve si odpovězte, co se může reálně rozbít. Pokud je riziko chyby v logice podmínek, použijte jednotkový test. Pokud je riziko v propojení s databází, souborovým systémem nebo cizí službou, integrační test je na místě. Typickou chybou je psát integrační test na všechno, co se dá, a pak trávit hodiny laděním prostředí. Druhým extrémem je jednotkové testy „nafukovat" tak, aby simulovaly vše, což vede k těžko udržovatelným mockům a testům, které neodrážejí realitu.
Další past: testy, které nejsou nezávislé. Pokud jeden test čeká na data vytvořená jiným testem, máte zaděláno na pořádný problém. Jakmile změníte pořadí spuštění, všechno se sype. Řešení je jednoduché – každý test si připraví vlastní data a po sobě uklidí. To platí pro všechny vrstvy pyramidy, ale u E2E je to kritické. Pokud test selže, musíte vědět, že to není kvůli stavu z předchozího testu.
Dále se zaměřte na dobu běhu. Pokud máte testy, které trvají déle než pět minut, rozdělte je do vrstev: rychlé (jednotkové), střední (integrace s jednou komponentou) a pomalé (end-to-end). Rychlé spouštějte při každém commitu, střední při každém pull requestu a pomalé až před nasazením do produkce. Tím zajistíte, že vývojáři dostanou zpětnou vazbu rychle, ale složité scénáře nezmizí. Nezapomeňte také na flaky testy – pokud test občas selže bez zjevné příčiny, buď ho opravte, nebo zahoďte. Jinak začnete ignorovat červené výsledky a celý systém ztratí důvěryhodnost.
Když tým začne psát automatizované testy, většinou skončí u rozsáhlých end-to-end scénářů, které procházejí celou aplikací. Na první pohled vypadají solidně, ale po pár týdnech se ukáže pravý opak: běh trvá desítky minut, každá změna v rozhraní rozbije desítky testů a doba opravy převyšuje čas, který testy ušetří. Základní poučka zní: čím výše v pyramidě test stojí, tím je dražší na údržbu a tím méně jich má být. Přesto ji týmy soustavně ignorují a pak řeší důsledky.
Při psaní nových testů dodržujte jednoduché pravidlo: jednotkový test pro logiku, integrační test pro spolupráci. Pokud píšete test pro třídu, která komunikuje s externí službou, nepoužívejte mock pro celé rozhraní, ale jen pro tu část, která je pro daný test podstatná. Tím předejdete tomu, že test projde, ale v reálném běhu se spojení rozpadne. Naopak u integračních testů nepoužívejte produkční data – vytvořte si malou testovací databázi s pevně danými hodnotami, abyste měli výsledky reprodukovatelné.
Prakticky doporučuji rozdělit testy do dvou vrstev podle rychlosti. Jednotkové testy spouštějte při každé změně kódu, měly by běžet pod deset sekund. Integrační testy zařaďte do samostatné fáze – ideálně při pushnutí do sdíleného repozitáře nebo v nočním běhu. Tím zajistíte, že vývojáři mají rychlou zpětnou vazbu při psaní kódu, ale zároveň se před nasazením ověří kritické scénáře. Důležité je, aby integrační testy byly deterministické – měly by běžet proti izolovanému prostředí, které je před každým během znovu vytvořeno.
Nakonec si rozmyslete, jak chcete, aby váš kód vypadal v budoucnu. Licence je závazná pro všechny, kdo kód získají, a není snadné ji změnit, pokud už ji někdo použil. Proto se vyplatí začít s licencí, která odpovídá vašim dlouhodobým záměrům, a ne s tou, kterou máte po ruce. Typickým omylem je přidat licenci až na konci projektu – potom už nemůžete ovlivnit, jak ji vnímalo předchozí šíření. Přidejte licenční soubor s plným zněním i krátký komentář v hlavičce každého souboru a ujistěte se, že máte od všech přispěvatelů souhlas s vydáním pod zvolenou licencí. Teprve pak máte jistotu, že vaše volba platí.
Poslední rada: pyramidu neberte jako dogma, ale jako výchozí bod. U projektu s bohatým uživatelským rozhraním a složitou logikou na klientovi bude poměr jiný než u REST API bez frontendu. Důležité je, abyste se rozhodovali vědomě a ne náhodně. Měřte si dobu běhu, počet selhání a čas strávený údržbou. Jakmile uvidíte, že opravy testů žerou víc času než psaní nových funkcí, je čas pyramidu přebudovat. A to je přesně ten moment, kdy se vyplatí mít na paměti, proč pyramida existuje – ne pro krásu, ale pro efektivitu.
Jak vypadá zdravá hierarchie a kde ji nejčastěji rozbijete Funkční základ pyramidy tvoří jednotkové testy. Měly by pokrývat izolovanou logiku bez závislostí na databázi, síti nebo časovačích. Pokud test potřebuje připojení k databázi nebo mockování pěti vrstev, není to jednotkový test, ale integrační test v převleku. Integrační testy patří do prostřední vrstvy – ověřují spolupráci modulů, ale stále by měly být rychlé a stabilní. Na vrcholu stojí malý počet E2E testů, které kontrolují kritické uživatelské cesty. Častá chyba? Píšete E2E testy pro každou maličkost, protože „to je přece nejvěrnější simulace". To je cesta do pekla.