IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 3 - Testování v JavaScriptu - Dokončení testů a best practices

V minulé lekci, Testování v JavaScriptu - Úvod do unit testů, jsme si připravili testovací projekt a připravili podstavu pro testování.

Dnes pokryjeme testy naše funkce, uvedeme si dostupné testovací metody a unit testy v JavaScriptu dovršíme přehledem best practices.

Jednotlivé testovací metody budou vždy testovat jednu metodu z naši kalkulačky, typicky pro několik různých vstupů.

Přidejme následujících 5 metod do souboru script.test.js:

test('sečte ruzná čísla a porovná s výstupem', () => {
    expect(Soucet(5, 10)).toBe(15);
    expect(Soucet(7, 11)).toBe(18);
    expect(Soucet(0, 5)).toBe(5);
});

test('odečte ruzná čísla a porovná s výstupem', () => {
    expect(Rozdil(10, 5)).toBe(5);
    expect(Rozdil(10, 10)).toBe(0);
    expect(Rozdil(2, 5)).toBe(-3);
});

test('vynásobí ruzná čísla a porovná s výstupem', () => {
    expect(Soucin(2, 2)).toBe(4);
    expect(Soucin(6, 0)).toBe(0);
    expect(Soucin(-4, 2)).toBe(-8);
    expect(Soucin(-4, -2)).toBe(8);
});

test('vydělí ruzná čísla a porovná s výstupem', () => {
    expect(Podil(10, 2)).toBe(5);
    expect(Podil(-10, -2)).toBe(5);
    expect(Podil(-10 , 2)).toBe(-5);
});

Všimněme si struktury testů. Využíváme funkce, které nám importoval Jest, a to funkci test(). Funkce jako první argument bere popis funkce. Vždycky bychom měli psát, co naše funkce dělá. Mějme taky na paměti, že již pracujeme se zadanými hodnoty. Druhý argument je anonymní funkce. V další fázi využíváme další importované funkce expect(). Ta přijímá testovanou hodnotu, na kterou budeme navazovat funkcí další, starající se o hodnotu očekávanou. V tomhle případě využijeme metody toBe(), která jako parametr bere právě očekávaný výstup.

Všimněme si, že zkoušíme různé vstupy, například jak negativní tak pozitivní čísla. V některých případech by nás mohla zajímat také maximální hodnota datových typů a podobně.

Dostupné testovací metody

  • .ToBe(hodnota) - Pokud chceme ověřit, jestli se hodnota rovná očekávané hodnotě.
  • .toHaveBeenCalled() - Zkontrolujeme, zda byla funkce zavolána.
  • .toHaveBeenCalledTimes(kolikrat) - Ověříme, zda byla funkce zavolána několikrát.
  • .toHaveBeenCalledWith(argument1, argument2, ...) - Ověří, jestli byla funkce zavolána s určitými argumenty.
  • .toHaveBeenLastCalledWith(arg1, arg2, ...) - Testujeme, s jakými argumenty byla funkce naposledy zavolána.
  • .toHaveReturned() - Kontrolujeme, jestli funkce něco vrátila.
  • .toHaveReturnedTimes(kolikrat) - Ověříme, zda funkce něco úspěšně vrátila několikrát.
  • .toHaveReturnedWith(hodnota) - Testujeme, zda funkce vrátila konkrétní hodnotu.
  • .toHaveLastReturnedWith(value) - Kontrolujeme, zda funkce naposledy vrátila konkrétní hodnotu.
  • .toHaveLength(cislo) - Používáme při ověření délky objektu.
  • .toHaveProperty(keyPath, hodnota?) - Kontrolujeme, zda objekt má přístup k dané vlastnosti. Můžeme testovat i hodnotu.
  • .toBeCloseTo(cislo, presnostNaKolikMist?) - Testujeme, zda se hodnota přibližně rovná. Používá se kvůli plovoucí čárce.
  • .toBeDefined() - Testuje, zda je metoda definována.
  • .toBeFalsy() - Testuje, zda výstup je false, 0, '', null, undefined, nebo NaN.
  • .toBeGreaterThan(cislo) - Můžeme zjistit, zda je hodnota větší než určité číslo.
  • a další...

Pravděpodobně již chápeme, co vše máme za možnosti. Pokud byste se chtěli dozvědět více metod a detaily, navštivte oficiální dokumentaci Jest.js.

Spouštění testů

Spuštění testů provedeme příkazem, který jsme si dříve definovali v package.json, tedy npm run test. Pokud se vše provedlo tak, jak mělo, náš test se provedl úspěšně a konzole nám dá vědět:

uspesne_testy - Testování v JavaScriptu

Výhoda je samozřejmě při implementaci nových věcí, kdy pomocí testů okamžitě poznáme, jestli je někde chyba. Modifikujme si funkci add() tak, aby na konci přičítala jedničku:

const Soucet = (a, b) => {
    return a + b + 1;
}

Test se nám již nesplní. Dále máme napsané, jaká hodnota byla vrácena ve skutečnosti oproti očekávané:

neuspesny_test - Testování v JavaScriptu

Best practices

Již v minulé lekci jsme nakousli best practices. Jelikož to je k unit testům v JavaScriptu vše, pojďme si na závěr vyjmenovat jakých častých chyb se vyvarovat, abychom dosáhli kvalitního výsledku.

  • Testujeme specifikaci, nikoli kód. Testy nikdy nepíšeme podle kódu nějaké metody, ale zamýšlíme se nad tím, k čemu metoda reálně slouží a co vše ji může přijít jako vstup.
  • Testujeme obecné knihovny, ne konkrétní logiku aplikace. Pokud je logika důležitá a obecná, měla by být vyčleněná do samostatné knihovny a ta by měla být poté testována.
  • Každý test by měl být úplně nezávislý na ostatních testech. Scénář by měl proběhnout i když metody libovolně proházíme a žádná metoda by po sobě neměla zanechávat nějaké změny (v souborech, v databázi a podobně), které by ovlivnily další metody. K dosažení tohoto chování často připravujeme prostředí pro jednotlivé metody v inicializační metodě a případně po nich ještě provedeme úklid v metodě úklidové. To samé platí i pro celé testy.
  • Každý test by měl dopadnout vždy stejně, bez ohledu na to, kdy jej spustíme. Pozor na testování generátorů náhodných výstupů a na práci s datem a časem.
  • Neprovádějte duplicitní porovnání, pokud nějaký vstup již ověřuje jiný test, neprovádějte toto ověření znovu.
  • Každý scénář testuje jen jednu jednotku. Váš software by měl být navržený tak, aby byl rozdělený na menší části, které mají minimální závislosti na ostatních a proto se dají jednoduše a nezávisle testovat (vzory high cohesion a low coupling).
  • Pokud testy vyžadují externí služby, měli bychom je tzv. mockovat. Tím vytváříme "falešné" služby se stejným rozhraním, které obvykle jen podstrkují testovací data. Využitím skutečných služeb bychom porušili nezávislost testů, jelikož by se navzájem začaly ovlivňovat. Méně elegantní řešení je vždy na začátku nastavit a na konci vrátit stav služeb.
  • Jako platí i všude jinde, vyhněte se zavádějícím názvům testů (jako vypocet(), vyjimka() a podobně). Programátoři často pojmenovávají testy i větším počtem slov, aby se poznalo co dělají. Běžně bychom to u metod neměli dělat, jelikož každá metoda dělá jen jednu činnost, ale u testů dává někdy smysl pojmenovat metody např. i takto obskurně KvadratickaRovnice_ZaporneKoeficienty_Vyjimka(), protože test často testuje více vstupů. V pojmenovávání testů byste měli být konzistentní. Nebojte se ani komentářů.
  • Testy by měly proběhnout rychle, jelikož v praxi obvykle testujeme všechny části aplikace různými typy testů a všechny časy se dokáží nasčítat do nepříjemné pauzy.

Vaše první unit testy nemusí být perfektní, stačí krátce otestovat to nejdůležitější. Uvidíte, že vám časem začnou selhávat a odhalovat chyby v implementaci. Čím je aplikace větší, tím o větší pokrytí testy (test code coverage) bychom se měli snažit. Pro dnešek to je vše, níže znova najdete soubory s přiloženým projektem.

V další lekci, Úvod do akceptačních testů a instalace Selenia, si uvedeme akceptační testy a nainstalujeme Selenium.


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 23x (12.44 MB)
Aplikace je včetně zdrojových kódů v jazyce JavaScript

 

Předchozí článek
Testování v JavaScriptu - Úvod do unit testů
Všechny články v sekci
Testování v JavaScriptu
Přeskočit článek
(nedoporučujeme)
Úvod do akceptačních testů a instalace Selenia
Článek pro vás napsal Filip Zeman
Avatar
Uživatelské hodnocení:
17 hlasů
Autor se věnuje vývoji aplikací v jazyce C# a Swift jak už ve sféře desktopové, tak mobilní či herní. Jako mladý člověk s nadšením sleduje nové technologie a postupy.
Aktivity