Provádění jednotkových testů s Jestem ve frontendových projektech

  • Jest nabízí výkonné, prakticky bezkonfigurační prostředí pro jednotkové testování pro frontendové projekty využívající JavaScript a React.
  • Jednotkové testy zlepšují včasnou detekci chyb, dokumentaci kódu a zvyšují bezpečnost refaktoringu.
  • Knihovna React Testing Library a Jestovy funkce mockingu, asynchronního testování a pokrytí usnadňují testování komponent a logiky rozhraní.
  • Integrace npm testů a reportů o pokrytí do každodenního pracovního postupu výrazně zvyšuje kvalitu a stabilitu frontendu.

žert

Pokud vyvíjíte rozhraní v Reactu nebo jiných frameworkech frontendDříve nebo později si uvědomíte, že spoléhat se pouze na „na mém počítači to funguje“ je zahrávání si s ohněm. Malá změna komponenty, rychlý refaktoring nebo aktualizovaná závislost mohou narušit části aplikace, aniž byste si toho vůbec všimli... Pokud jste to neudělali... dobrý systém pro jednotkové testování nastavený pomocí Jestu.

Moderní ekosystém JavaScriptu má automatizované testování v DNA. Nástroje jako existuje oni dělají Pište testy pro komponentuPoužívání funkcí a hooků by mělo být v každodenní práci zvládnutelné, i když nejste nadšený testovací nadšenec. Klíčem je pohodlné nastavení, pochopení psaní testů a znalost interpretace výsledků a pokrytí, abyste identifikovali oblasti kódu, které zůstávají netestované.

Proč provádět unit testování ve frontendových projektech?

Jednotkové testy jsou malé testy, které ověřují konkrétní části vašeho kódu (funkce, komponenty, hooky, utility…). Ve frontendovém vývoji jsou obzvláště užitečné, protože se rozhraní často mění, existuje stavová logika, uživatelské události, asynchronní volání atd. Bez bezpečnostní sítě je každá změna hazardem.

Mezi nejzřetelnější výhody jednotkového testování patří včasné odhalení chybMísto objevování chyb, když je uživatel již v produkci, je detekujete ihned po uložení změn a spuštění testovací sady, což vám pomůže lépe porozumět životní cyklus chybyTo ušetří týmu čas, peníze a spoustu bolestí hlavy.

Dalším velmi silným bodem je, že Testy nakonec fungují jako živá dokumentace.Z toho, jak je test komponenty nebo funkce napsán, je jasné, jak se má používat, jaké vstupy přijímá a jaké výsledky by měl vracet. U velkých projektů je to pro nové členy týmu neocenitelné.

V kontextu JavaScriptu a Reactu, Psaní testů také pomáhá lépe modularizovat kódAbyste mohli testovat součást samostatně, potřebujete ji dobře izolovat, s jasnými závislostmi a definovanými odpovědnostmi, což se ve střednědobém a dlouhodobém horizontu promítá do udržovatelnějšího frontendu.

žert

Co je Jest a proč se tolik používá ve frontend vývoji?

Jest je framework pro testování JavaScriptu, původně vyvinutý společností Facebook., navržený pro skvělou spolupráci s Reactem, ale dokonale vhodný pro jakýkoli klientský nebo serverový JavaScriptový nebo TypeScriptový projekt.

Jednou z jeho velkých výhod je filozofie „nulové konfigurace“V mnoha projektech stačí pouhá instalace a přidání skriptu do souboru package.json k zahájení testování, aniž byste se museli zabývat složitými konfiguračními soubory. Díky tomu je obzvláště atraktivní ve frontendových prostředích, kde se již používá mnoho nástrojů.

Jest se standardně integruje Klíčové vlastnosti pro frontendové projektyRychlé provádění testů, režim sledování, který po detekci změn znovu spustí testy, velmi pohodlná podpora asynchronního kódu, simulace závislostí pomocí mocků a špionážních nástrojů a generování reportů o pokrytí kódu bez nutnosti spoléhat se na další externí nástroje.

U frontendových projektů s Reactem se Jest téměř vždy kombinuje s Knihovna pro testování ReactuTato knihovna usnadňuje testování komponent prostřednictvím jejich chování a vykreslování, spíše než aby byla příliš vázána na interní implementaci. Mezi těmito dvěma nástroji můžete pokrýt prakticky všechny vaše běžné potřeby testování rozhraní.

Testovací knihovna pro komponenty v Jestu a Reactu

Instalace testovací knihovny Jest a React do frontendového projektu

Prvním krokem k zahájení práce s Jestem je jeho přidání jako vývojové závislosti. ve vašem projektu. Pokud používáte npm, typický příkaz by byl:

npm install --save-dev jest

Pokud dáváte přednost práci s přízíMůžete jej nainstalovat pomocí:

přidat přízi --dev jest

V projektech založených na Reactu je velmi běžné instalovat také knihovnu React Testing Library., který se skládá z několika balíčků: základního @testing-library/react pro komponenty, @testing-library/jest-dom pro další porovnávače v DOMu a často @testing-library/user-event pro simulaci složitých uživatelských interakcí.

Typické nastavení Reactu by mohlo vypadat nějak takto:

npm install –save-dev @testing-library/react @testing-library/jest-dom @testing-library/user-event

S těmito závislostmi je vaše prostředí připraveno k psaní komponentně orientovaných jednotkových testů., události a výsledky viditelné pro uživatele, vždy se spoléhající na Jest jako hlavní engine pro provádění testů.

Základní konfigurace Jestu v package.json

Jakmile je Jest nainstalován, je třeba projektu sdělit, jak budou testy spouštěny.Obvyklou praxí je přidat do souboru package.json skript, který umožňuje jednoduchý příkaz z terminálu.

Minimálním příkladem konfigurace by mohl být:

{ «skripty»: { «test»: «jest» } }

S tímto skriptem můžete spustit všechny testy projektu pouhým spuštěním:

npm test

nebo, pokud používáte přízi, s:

test příze

Jest automaticky detekuje testovací soubory na základě jejich názvu.Ve výchozím nastavení bude ve stromu složek hledat soubory s příponami .test.js nebo .spec.js, takže obvykle není nutné zadávat cesty ručně, pokud budete respektovat tyto konvence.

Testovací soubory a příklady Jestu

Konvence souborů: přípona .test.js a struktura testu

Aby Jest mohl rozpoznat vaše testy bez další konfigurace, Důrazně se doporučuje použít rozšíření .test.js. (nebo .test.ts, pokud pracujete s TypeScript). Pokud máte například komponentu Button.js, velmi běžný název pro její test by byl Button.test.js ve stejném adresáři nebo v samostatné složce tests.

Tato úmluva má dvě jasné výhody:

  • Na jedné straně Jest automaticky vyhledá soubory, které mají být spuštěny.
  • Na druhou stranu, každý, kdo je v projektu nový, okamžitě ví, které soubory obsahují produkční kód a které testy.

Testy jsou definovány pomocí testovací funkce nebo její aliaskde první argument je textový popis toho, co kontrolujete, a druhý je funkce, která provádí testovací logiku. V rámci této funkce se aserce používají prostřednictvím `expect` a jeho různých porovnávačů.

V komponentách Reactu je struktura podobnáJenže místo testování čisté funkce vykreslíte komponentu pomocí knihovny React Testing Library, vyhledáte prvky na obrazovce (podle textu, role, popisků atd.) a zkontrolujete, zda se zobrazují nebo reagují podle očekávání při simulaci uživatelských interakcí.

Napište svůj první unit test v Jestu

Abych tohle všechno přinesl na zem, Představte si jednoduchou funkci, která sčítá dvě hodnotyV souboru s názvem sum.js definujte funkci sum(a, b) { return a + b; } a exportujte ji. Poté v souboru sum.test.js tuto funkci importujte a definujte test s jasným popisem toho, co se má stát.

Testovací tělo je omezeno na spuštění funkce a ověření výsledku.Voláte sum(1, 2) a používáte expect k označení, že hodnota musí být přesně 3. Pokud funkce přestane vracet tento výsledek (kvůli chybě nebo nepředvídané úpravě), Jest označí test jako neúspěšný.

Tento typ testu, ať se může zdát jakkoli jednoduchý, je základem jednotkového testování.Každá funkce nebo logická jednotka má jeden nebo více testů, které popisují, co by měla dělat v různých scénářích, takže jakákoli odchylka od očekávaného chování je okamžitě patrná pouhým spuštěním sady testů.

U frontendových komponent je přístup stejně přímočarýVykreslíte komponentu, zkontrolujete, co se zobrazuje, simulujete události, jako jsou kliknutí nebo zápis do vstupů, a ověříte, zda výsledný stav a DOM odpovídají tomu, co definuje funkční návrh aplikace.

Jak projekt poroste, budete přidání dalších testů pro pokrytí hraničních případůatypické položky, chyby a méně zřejmé situace, čímž se posiluje spolehlivost aplikace a zabraňuje regresím při zavádění nových funkcí.

Jest Matchers: různé způsoby kontroly výsledků

Jádrem tvrzení v Jest je funkce očekáváníkterý je propojen s různými porovnávači pro specifikaci požadavků na přijatou hodnotu. V závislosti na tom, co testujete, budete chtít použít jeden nebo druhý. Toto jsou nejpraktičtější porovnávače:

  • Být. Kontroluje striktní rovnost, což v JavaScriptu znamená stejnou hodnotu a stejný typ, což je velmi užitečné pro čísla, řetězce nebo booleovské hodnoty, kde očekáváte přesnou shodu. Pokud očekáváte 3, nechcete, aby se objevila „3“.
  • toEqualUžitečné při práci s objekty nebo poli. Tento porovnávač porovnává strukturu a obsah objektů, takže můžete ověřit, zda funkce vrací objekt se správnými vlastnostmi a hodnotami, i když interní odkaz není stejný.
  • ne. Pokud se v jakémkoli okamžiku potřebujete ujistit, že se něco NESTÁ, můžete použít negaci `not`. Například `expect(value).not.toBe(0)` jasně ukazuje, že číslo by nemělo být nula, nebo `expect(array).not.toEqual([])` označuje, že neočekáváte prázdné pole.

Kromě těchto základů nabízí Jest mnoho dalších další dohazovači: zkontrolovat, zda funkce vyvolá chybu, zda pole obsahuje specifický prvek, zda řetězec odpovídá regulárnímu výrazu nebo, v případě Reactu s jest-dom, zda je prvek DOM viditelný, zakázaný, zda obsahuje určitý text atd.

Asymetrické testy JEST

Asynchronní testování v Jestu: promise, async/await a callbacky

Moderní frontend je plný asynchronní operaceHTTP požadavky, časovače, interakce uživatelů, které spouštějí aktualizace stavu atd. Proto Jest integruje několik způsobů, jak pohodlně pracovat s asynchronními testy.

Nejčistší a nejběžnější způsob testování asynchronní logiky je použít async/awaitTestovací funkci deklarujete jako asynchronní, čekáte na vyřešení kontrolovaného promisu a poté provedete obvyklá tvrzení s expectem na přijatém výsledku.

Například byste mohli mít funkci fetchData, která vrací promise, a napsat asynchronní test, který volá fetchData, čeká na její vyřešení a ověří, zda vrácená data odpovídají tomu, co očekáváte, ať už se jedná o konkrétní text nebo objekt s určitou strukturou.

Jest také přímo podporuje promisy bez async/await.Vrácení samotného promisu z testu, aby framework věděl, kdy je operace dokončena. Navíc ve starších nebo velmi specifických případech umožňuje použití zpětných volání s parametrem `done` k označení konce testu.

V oblasti knihovny pro testování Reactu, Asynchronní testy často kombinují čekání s findBy nebo waitFor., které umožňují čekat na aktualizaci DOM po požadavku nebo změně stavu před provedením příslušných tvrzení.

Mocking v Jestu: simulace modulů, funkcí a závislostí

Základním principem jednotkového testování je izolovat testovanou jednotkuTo znamená, že pokud funkce nebo komponenta závisí na externích službách (API, knihovnách třetích stran, náročných modulech atd.), budete chtít toto chování simulovat, spíše než ho během testu skutečně spouštět.

Jest usnadňuje tuto izolaci pomocí napodobenin (mocků)Pomocí jest.fn můžete vytvářet falešné funkce, které zaznamenávají, kolikrát jsou volány, s jakými argumenty nebo jakou hodnotu by měly vrátit. To je velmi užitečné pro testování interních interakcí, aniž byste se museli dotýkat skutečného kódu těchto služeb.

Když potřebujete jít o krok dál, jest.mock umožňuje nahradit celé modulyMůžete určit, že při importu konkrétního souboru by Jest měl použít fiktivní implementaci, která vrací řízené hodnoty, a vyhnout se tak například odesílání skutečných HTTP požadavků při každém spuštění testovací sady.

V komponentách React se mocky často používají k simulaci vlastních hooků., datové služby nebo moduly, které spravují lokální úložiště, analytiku atd., přičemž test se zaměřuje na chování komponenty a nikoli na její externí závislosti.

Používá se správně, Mocking výrazně urychluje provádění testů. a umožňuje snadno reprodukovat chybové scénáře, podivné odpovědi serveru nebo atypické stavy, kterých by bylo obtížné dosáhnout interakcí se skutečnými službami.

Organizace a seskupování testů pomocí bloků popisuje

S růstem vaší testovací sady budete potřebovat udržovat minimální objednávku Aby se člověk neztratil mezi stovkami testů rozmístěných po více souborech, Jest nabízí bloky jako přirozený způsob seskupování souvisejících testů.

S popisem můžete uzavřete několik testů ve stejném kontextuNapříklad „aritmetické operace“ nebo „chování komponenty záhlaví“. V rámci bloku každý test popisuje konkrétní případ, ale sada se čte jako jakýsi souvislý příběh o dané části kódu.

Tato organizace pomáhá jak při čtení, tak při ladění.Když se něco pokazí, je snazší najít testovací skupinu a pochopit, které části systému se to týká, aniž byste museli prohledávat celý projekt.

Navíc, popisuje, jak se velmi dobře kombinuje s hooky životního cyklu Jestu, například beforeEach nebo afterEach, což vám umožňuje připravit data nebo vymazat sdílené stavy pro všechny testy v rámci stejného bloku, čímž se zabrání duplicitní inicializační logike v každém jednotlivém testu.

U komplexních frontendových projektů je běžné mít popis pro každou komponentu., v případě potřeby rozdělené na interní popisy pro různé režimy, vlastnosti nebo interakční toky, což z testovacího souboru dělá poměrně jasnou mapu všeho, co se od dané komponenty očekává.

Využití npm testování a exekuční disciplíny v pracovním postupu

Po dokončení základní konfigurace, Příkaz npm test se stane vaším každodenním spojencemSpuštění před nahráním změn by mělo být téměř automatické gesto, jako uložení souboru nebo spuštění linteru.

Mnoho týmů přijímá nepsané pravidlo, že pokud testy selžou, nic se nezavazují.Tato praxe zabraňuje selhání hlavní větve projektu a udržuje garantovanou minimální kvalitu v každém požadavku na sloučení nebo stažení, který je integrován do repozitáře.

Jest také nabízí velmi užitečný interaktivní režim ve vývojiSpuštěním npm testu v režimu sledování framework znovu spustí pouze testy související s upravenými soubory, což výrazně zrychlí cyklus testování a opravování při vývoji nových funkcí nebo opravě chyb.

Integrace Jestu do systému kontinuální integrace (CI) jako Akce GitHub dokončit kruhPokaždé, když někdo nahraje kód do vzdáleného repozitáře, CI server spustí npm test a v případě selhání integrace zablokuje integraci, čímž zabrání šíření chyb do sdílených prostředí.

Pokrytí kódu: měření toho, kolik je skutečně testováno

Nestačí mít jen písemné testy. Je také zajímavé vědět, do jaké míry pokrývají kód.Za tímto účelem Jest integruje reporting o pokrytí, který ukazuje, které řádky, funkce a větve byly během testování provedeny.

Generování těchto reportů je stejně jednoduché jako přidání příznaku --coverage k příkazu test.Například můžete nakonfigurovat skript package.json jako „test“: „jest --coverage“ nebo spustit npm test --coverage, pokud chcete podrobnou zprávu.

Výsledek zahrnuje procenta pokrytí na soubor a na globální úrovniUvidíte, které soubory mají dobré pokrytí a kterých se během testování sotva dotknete, což vám pomůže rozhodnout se, kde se vyplatí investovat více úsilí do psaní dalších testů.

Samozřejmě stojí za to si to připomenout 100% pokrytí nezaručuje absenci chybJe možné spustit všechny řádky kódu s nenáročnými testy, takže kvalita asercí je stejně důležitá, nebo dokonce důležitější než samotné číslo.

Použijte pokrytí jako hrubý ukazatel v kombinaci s revizemi kódu a zdravým rozumemJe to dobrý způsob, jak udržet rovnováhu mezi testovacím úsilím a skutečnými přínosy pro stabilitu projektu.

Se vším viděným, Používání Jestu a nástrojů, jako je React Testing Library, ve frontendových projektech Stává se to docela logickým rozhodnutímUmožňuje vám ověřit, zda každá komponenta a funkce dělá to, co má, snadno spouštět testy pomocí npm test, monitorovat pokrytí pomocí --coverage a udržovat solidní kódovou základnu, kde je mnohem bezpečnější vyvíjet produkt bez obav z narušení toho, co již funguje.

Vytvoření kanálu CI/CD pomocí akcí GitHubu
Související článek:
Jak vytvořit robustní CI/CD pipeline pomocí akcí GitHub

Přidat jako preferovaný zdroj v Googlu