Takéunit testing, unit testsPokročilý
Definice
Unit test je automatizovaný test malé části programu, typicky jedné funkce, metody nebo třídy, který ověřuje její chování izolovaně od zbytku systému. Pomáhá rychle odhalit regresi, zpřesňuje návrh rozhraní a dává vývojářům jistotu při refaktoringu i změnách závislého kódu v týmu.
Co jednotkový test skutečně ověřuje
Jednotkový test ověřuje malou jednotku programu podle očekávaného chování, ne podle aktuální implementace. Jednotkou může být čistá funkce, metoda služby, validační pravidlo nebo malý objekt. Dobrý test říká: pro daný vstup má kód vrátit určitý výsledek, vyvolat konkrétní výjimku nebo zavolat závislost správným způsobem.
Hodnota jednotkového testu roste hlavně tam, kde je rozhodování v kódu nenápadné: okrajové hodnoty, prázdné vstupy, zaokrouhlování, oprávnění nebo převody formátů. Test pak slouží jako pojistka proti regresi i jako živá dokumentace domluveného chování.
Izolace od databáze, sítě a času
Unit test nemá být závislý na dostupnosti databáze, platební brány, souborového systému ani skutečného času. Externí závislosti se obvykle nahrazují testovací dvojníkem, například stubem nebo mock objektem. Cílem není předstírat celý svět, ale odstranit náhodu a zúžit příčinu případného selhání.
Izolace má praktický dopad na diagnostiku. Když jednotkový test spadne, vývojář má vědět, která malá část logiky porušila očekávání. Pokud test zároveň čeká na síť, mění data v databázi a spoléhá na pořadí běhu, chyba už nemusí být v testované jednotce. Takový test může být užitečný, ale patří spíš mezi integrační testy.
Rychlost jako součást návrhu testů
Jednotkové testy se mají spouštět často: při ukládání změn, před commitem i v kontinuální integraci. Rychlost proto není pohodlný bonus, ale konstrukční požadavek. Pomalé testy tým postupně přestane spouštět lokálně, takže ztratí největší výhodu: okamžitou zpětnou vazbu.
Rychlý test bývá krátký, deterministický a čitelný. Typický zápis používá strukturu arrange, act, assert: připrav data, proveď testovanou operaci, ověř výsledek. Test by měl selhat z jednoho jasného důvodu. Příliš mnoho nesouvisejících kontrol v jednom testu sice sníží počet souborů, ale zhorší hledání příčiny.
Proč jednotkové testy nenahradí ostatní testování
Unit test dobře chrání vnitřní logiku, ale neověří, že aplikace správně komunikuje s reálnou databází, prohlížečem, frontou zpráv nebo externím API. Integrace může selhat i tehdy, když všechny malé části prošly samostatně. Proto se jednotkové testy kombinují s integračními, end-to-end a ručním průzkumným testováním.
Největší přínos jednotkových testů bývá u kódu, který se bude měnit. Refaktoring je bezpečnější, protože testy popisují chování, které má zůstat zachované. Slabý přínos mají testy, které jen kopírují implementaci, kontrolují privátní detaily nebo vyžadují přepis při každé nevýznamné úpravě struktury kódu.
Příklady z praxe
Sleva v košíku e-shopu
E-shop počítá cenu po slevě a vývojář přidá jednotkový test pro běžný i neplatný vstup. Když později někdo změní pravidla zaokrouhlování nebo omylem povolí slevu nad 100 %, test spadne ještě před nasazením. Chyba se najde v malé funkci, ne až v objednávkovém procesu.
import unittest def apply_discount(price, percent): if percent < 0 or percent > 100: raise ValueError("percent must be between 0 and 100") return price * (100 - percent) / 100 class DiscountTest(unittest.TestCase): def test_applies_percentage_discount(self): self.assertEqual(apply_discount(200, 25), 150) def test_rejects_invalid_discount(self): with self.assertRaises(ValueError): apply_discount(200, 120) if __name__ == "__main__": unittest.main()Oprávnění v administraci
Redakční systém povoluje publikování jen aktivním editorům. Jednotkový test ověří rozhodovací funkci bez databáze, přihlášení a administrace. Pokud refaktoring oprávnění omylem pustí neaktivního uživatele, selhání ukáže přímo na pravidlo, které se změnilo.
import test from 'node:test'; import assert from 'node:assert/strict'; function canPublish(user) { return user.role === 'editor' && user.active === true; } test('active editor can publish', () => { assert.equal(canPublish({ role: 'editor', active: true }), true); }); test('inactive editor cannot publish', () => { assert.equal(canPublish({ role: 'editor', active: false }), false); });
Časté omyly
- MýtusUnit test musí mít každá metoda ve třídě.
- Ve skutečnostiJednotkový test má chránit důležité chování, ne mechanicky kopírovat strukturu kódu. Některé metody jsou jen implementační detail a dávají větší smysl testovat přes veřejné rozhraní.
- MýtusKdyž máme hodně unit testů, aplikace je otestovaná.
- Ve skutečnostiUnit testy neověří celé propojení systému. Aplikace může mít výborně pokrytou logiku a přesto selhat na migraci databáze, konfiguraci, síti nebo chování prohlížeče.
Časté dotazy
- Má unit test kontrolovat privátní metody?
- Unit test má testovat veřejně pozorovatelné chování malé části kódu: návratovou hodnotu, vyvolanou chybu, změnu stavu nebo komunikaci s jasně definovanou závislostí. Jednotkový test obvykle nemá opisovat každý řádek implementace. Test privátní metody často prozrazuje, že se test příliš váže na vnitřní strukturu a bude křehký při refaktoringu.
- Které části aplikace dávají pro unit test největší smysl?
- Unit test je vhodný pro business logiku, validační pravidla, výpočty, parsování a rozhodovací větve. Uživatelské rozhraní, databázové dotazy a komunikace mezi službami často potřebují jiné druhy testů. Jednotkové testování samo o sobě nezaručí, že celek funguje v produkčním prostředí, ale výrazně snižuje počet chyb v izolované logice.
- Kdy má unit test používat mock?
- Unit test může používat mock, když testovaná jednotka potřebuje závislost, která je pomalá, nedeterministická nebo mimo proces aplikace. Mock se nehodí jako náhrada za každou spolupracující třídu. Přehnané mockování vede k testům, které potvrzují implementační detaily místo užitečného chování, takže se rozbíjejí při bezpečném refaktoringu.
- Jak poznat dobrý unit test v praxi?
- Unit test se v týmu pozná podle toho, že běží rychle, selhává deterministicky, nevyžaduje sdílené prostředí a má jasný důvod existence. Samotný počet testů není dobré měřítko. Užitečnější je sledovat, zda testy chrání důležité chování, zjednodušují změny a dávají srozumitelnou chybovou zprávu při porušení očekávání.
Zdroje
- unittest — Unit testing framework(otevře se v novém okně)
- Test runner(otevře se v novém okně)
- Unit testing best practices(otevře se v novém okně)
- Unit testing(otevře se v novém okně)