3. diel - Testovanie v JavaScripte - Dokončenie testy a best practices
V minulej lekcii, Testovanie v JavaScripte - Úvod do unit testov , sme si pripravili testovacie projekt a pripravili podstavu pre testovanie.
Dnes pokryjeme testy naše funkcie, uvedieme si dostupné testovacie metódy a unit testy v Javascriptu dovŕšite prehľadom best practices.
Jednotlivé testovacie metódy budú vždy testovať jednu metódu z našu kalkulačky, typicky pre niekoľko rôznych vstupov.
Pridajme nasledujúcich 5 metód do súboru 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šimnime si štruktúry testov. Využívame funkcie, ktoré nám importoval
Jest, a to funkciu test. Funkcie ako prvý argument berie popis funkcie. Vždy
by sme mali písať, čo naše funkcie robí. Majme taky na pamäti, že už
pracujeme so zadanými hodnoty. Druhý argument je anonymný funkcie. V ďalšej
fáze využívame ďalšie importované funkcie expect()
. Tá
prijíma testovanú hodnotu, na ktorú budeme nadväzovať funkcií ďalšie,
starajúci sa o hodnotu očakávanú. V tomto prípade využijeme metódy
toBe()
, ktorá ako parameter berie práve očakávaný výstup.
Všimnime si, že skúšame rôzne vstupy, napríklad ako negatívne tak pozitívne čísla. V niektorých prípadoch by nás mohla zaujímať tiež maximálna hodnota dátových typov a podobne.
Dostupné testovacie metódy
.ToBe(hodnota)
- Ak chceme overiť, či sa hodnota rovná očakávanej hodnote..toHaveBeenCalled()
- Skontrolujeme, či bola funkcia zavolaná..toHaveBeenCalledTimes(kolikrat)
- Overíme, či bola funkcia zavolaná niekoľkokrát..toHaveBeenCalledWith(argument1, argument2, ...)
- Overí, či bola funkcia zavolaná s určitými argumenty..toHaveBeenLastCalledWith(arg1, arg2, ...)
- Testujeme, s akými argumentmi bola funkcia naposledy zavolaná..toHaveReturned()
- Kontrolujeme, či funkcie niečo vrátila..toHaveReturnedTimes(kolikrat)
- Overíme, či funkcia niečo úspešne vrátila niekoľkokrát..toHaveReturnedWith(hodnota)
- Testujeme, či funkcia vrátila konkrétnu hodnotu..toHaveLastReturnedWith(value)
- Kontrolujeme, či funkcie naposledy vrátila konkrétnu hodnotu..toHaveLength(cislo)
- Používame pri overení dĺžky objektu..toHaveProperty(keyPath, hodnota?)
- Kontrolujeme, či objekt má prístup k danej vlastnosti. Môžeme testovať aj hodnotu..toBeCloseTo(cislo, presnostNaKolikMist?)
- Testujeme, či sa hodnota približne rovná. Používa sa kvôli plávajúce čiarke..toBeDefined()
- Testuje, či je metóda definovaná..toBeFalsy()
- Testuje, či výstup je false, 0, '', null, undefined, alebo NaN..toBeGreaterThan(cislo)
- Môžeme zistiť, či je hodnota väčšia ako určité číslo.- a ďalšie ...
Pravdepodobne už chápeme, čo všetko máme za možnosti. Ak by ste sa chceli dozvedieť viac metód a detaily, navštívte oficiálne dokumentáciu Jest.js.
Spúšťanie testov
Spustenie testov prevedieme príkazom, ktorý sme si predtým definovali v
package.json, teda npm run test
. Ak sa všetko
vykonalo tak, ako malo, náš test sa vykonal úspešne a konzoly nám dá
vedieť:
Výhoda je samozrejme pri implementácii nových vecí, kedy pomocou testov
okamžite spoznáme, či je niekde chyba. Modifikujte si funkciu
add()
tak, aby na konci pripísala jedničku:
const Soucet = (a, b) => { return a + b + 1; }
Test sa nám už nesplní. Ďalej máme napísané, aká hodnota bola vrátená v skutočnosti oproti očakávanej:
Best practices
Už v minulej lekcii sme načali best practices. Keďže to je k unit testom v JavaScripte všetko, poďme si na záver vymenovat akých častých chýb sa vyvarovať, aby sme dosiahli kvalitného výsledku.
- Testujeme špecifikáciu, nie kód. Testy nikdy nepíšeme podľa kódu nejaké metódy, ale zamýšľame sa nad tým, k čomu metóda reálne slúži a čo všetko ju môže prísť ako vstup.
- Testujeme všeobecné knižnice, nie konkrétnej logiku aplikácie. Ak je logika dôležitá a všeobecná, mala by byť vyčlenená do samostatnej knižnice a tá by mala byť potom testovaná.
- Každý test by mal byť úplne nezávislý od ostatných testoch. Scenár by mal prebehnúť aj keď metódy ľubovoľne proházíme a žiadna metóda by po sebe nemala zanechávať nejaké zmeny (v súboroch, v databáze a podobne), ktoré by ovplyvnili ďalšie metódy. Na dosiahnutie tohto správania často pripravujeme prostredie pre jednotlivé metódy v inicializačnú metóde a prípadne po nich ešte prevedieme upratovanie v metóde upratovacie. To isté platí aj pre celé testy.
- Každý test by mal dopadnúť vždy rovnako, bez ohľadu na to, kedy ho spustíme. Pozor na testovanie generátorov náhodných výstupov a na prácu s dátumom a časom.
- Nevykonávajte duplicitné porovnanie, ak nejaký vstup už overuje iný test, nerobte toto overenie znovu.
- Každý scenár testuje len jednu jednotku. Váš softvér by mal byť navrhnutý tak, aby bol rozdelený na menšie časti, ktoré majú minimálne závislosti na ostatných a preto sa dajú jednoducho a nezávisle testovať (vzory high cohesion a low coupling).
- Ak testy vyžadujú externé služby, mali by sme ich tzv. Mocková. Tým vytvárame "falošné" služby s rovnakým rozhraním, ktoré zvyčajne len podstrkuje testovacie dáta. Využitím skutočných služieb by sme porušili nezávislosť testov, pretože by sa navzájom začali ovplyvňovať. Menej elegantné riešenie je vždy na začiatku nastaviť a na konci vrátiť stav služieb.
- Ako platí aj všade inde, vyhnite sa zavádzajúcim
názvom testov (ako
vypocet()
,vyjimka()
a podobne). Programátori často pomenúvajú testy aj väčším počtom slov, aby sa spoznalo čo robia. Bežne by sme to pri metódach nemali robiť, pretože každá metóda robí len jednu činnosť, ale u testov dáva niekedy zmysel pomenovať metódy napr. Aj takto ObskurníKvadratickaRovnice_ZaporneKoeficienty_Vyjimka()
, pretože test často testuje viac vstupov. V pomenovávanie testov by ste mali byť konzistentné. Nebojte sa ani komentárov. - Testy by mali prebehnúť rýchlo, pretože v praxi zvyčajne testujeme všetky časti aplikácie rôznymi typmi testov a všetky časy sa dokážu sčíta do nepríjemnej pauzy.
Vaša prvá unit testy nemusí byť perfektné, stačí krátko otestovať to najdôležitejšie. Uvidíte, že vám časom začnú zlyhávať a odhaľovať chyby v implementácii. Čím je aplikácia väčšia, tým o väčšie pokrytie testy (test code coverage) by sme sa mali snažiť. Pre dnešok to je všetko, nižšie znova nájdete súbory s priloženým projektom.
V ďalšej lekcii, Úvod do akceptačných testov a inštalácia Selenia , si uvedieme akceptačné testy a nainštalujeme Selenium.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 27x (12.44 MB)
Aplikácia je vrátane zdrojových kódov v jazyku JavaScript