6. diel - Automatické testovanie v JavaScripte
V minulej lekcii, Debugging vo vývojovom prostredí webstore , sme si povedali niečo o Debugging priamo vo vývojovom prostredí webstore.
Keď prvýkrát počujeme slovo testovanie, vybavíme si pravdepodobne proces debuggovania, ktorý sme si popísali doteraz. Napísali sme časť kódu a spustili ho, aby sme zistili, či dostaneme očakávané výsledky. Hoci toto budeme robiť stále, existuje možnosť, ako tento proces do určitej miery automatizovať, a to za použitia tzv. Unit testov. Už od názvu vypovedá, že vezmeme oddeliteľnou časť kódu a otestujeme, či vracia očakávaný výsledok. Dobrý dôvod k tomu písať testy je ten, že okamžite vidíme vplyv nového kódu na funkcionalitu. Samozrejme aj unit testy majú svoje miesto. Bolo by zbytočné ich použiť u aplikácie o pár riadkoch, avšak vo väčšom a obsiahlejším projektu nám môžu spríjemniť život. Popíšeme si tiež testy integračné a princíp testovanie end-to-end.
Využijeme kódu pre sčítanie dvoch čísel, zvlášť upraveného na účely článku:
<!DOCTYPE html> <html> <head> <title>Sčítač</title> <script src="script.js"></script> <meta charset="utf-8"> </head> <body> <p>Číslo 1</p> <input id="a" type="number"> <p>Číslo 2</p> <input id="b" type="number"> <br /> <br /> <input id="button" type="button" onclick="addDisplay()" value="Sečíst"> <p id="result">0</p> </body> </html>
function addDisplay() { let number1 = parseInt(document.getElementById("a").value); let number2 = parseInt(document.getElementById("b").value); document.getElementById("result").innerHTML = addNumbers(number1, number2); } const addNumbers = (number1, number2) => { if (testValidity) { return add(number1, number2); } else { return false; } } const add = (number1, number2) => { return number1 + number2; } const testValidity = (firstNumber, secondNumber) => { if (!isNaN(firstNumber) && !isNaN(secondNumber)) { return true; } else { return false; } } exports.add = add; exports.testValidity = testValidity; exports.addNumbers = addNumbers;
Unit testy
Najprv potrebujeme niečo, čo nám testy vie spustiť a zobraziť nám
výsledky. K tomuto využijeme populárne knižnicu Jest. V
tomto článku budem opäť pracovať s vývojovým prostredím Visual Studio
Code. Pomocou neho Jest nainštalujeme využitím terminálu, ktorý možno
zobraziť klávesovou skratkou Ctrl +;. Do terminálu
napíšeme npm install --save-dev jest
a počkáme na dokončenie
procesu.
Písanie testov
Ukážeme si jednoduchý príklad unit testu, a to na funkciu add (number1, number2). Aby sme mohli začať testovať, musíme si vytvoriť nový súbor v rovnakom adresári, ako je náš skript script.js. Súbor pomenujeme rovnako, akurát k nemu pridáme koncovku čiže script.test.js. Jest podľa koncovky automaticky rozozná, že sa jedná o súbor pre testy. Najprv funkciu musíme importovať:
const {add} = require('./script');
Ako ďalšie využijeme 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é:
test('sečte 5 a 10 má se rovnat 15', () => { });
V tele funkcie si vytvoríme konštantu, ktorá uloží súčet dvoch čísel
za pomocou našej funkcie add()
:
const number = add(5, 10);
Predpokladáme, že sa výstup bude rovnať číslu 15
, pre to
využijeme importovanú funkciu expect()
, ktorá v parametri berie
hodnotu, ktorá sa má porovnať, v našom prípade konštanta
number. Na túto funkciu môžeme ďalej zavolať funkcie k
otestovaniu, či je hodnota číslo, porovnať ju, zistiť, či je definovaná a
mnoho ďalšieho. My využijeme funkciu Tobe (), ktorá ako
parameter berie očakávaný výstup. Celý riadok bude teda vyzerať
nasledovne:
expect(number).toBe(15);
Celá funkcia je teda taká:
test('sečte 5 a 10 má se rovnat 15', () => { const number = add(5, 10); expect(number).toBe(15); });
Spúšťanie testov
Ako časť nastavenia si vytvoríme súbor package.json a vložíme do neho nasledujúce riadky:
{ "scripts": { "test": "jest" } }
To nám umožní testy spúšťať priamo v termináli. To urobíme pomocou
príkazu npm run test
. Ak sa všetko vykonalo tak ako malo, náš
test sa vykonal úspešne:
Výhoda je samozrejme pri implementácii nových vecí, kedy pomocou testov
spoznáme okamžite, či je niekde chyba. Modifikujte si funkciu
add()
tak, aby na konci pripísala jedničku:
function add(number1, number2) { return number1 + number2 + 1; }
Test sa nám už nesplní. Ďalej máme napísané, aká hodnota bola vrátená v skutočnosti oproti očakávanej:
Pre jednu funkciu samozrejme možno písať viac testov. Mohli by sme testovať, či je výstup číslo či zabrániť falošne pozitívnemu testu sčítaním dvoch ostatných položiek.
Pridať si môžeme aj test pre metódu testValidity()
.
Nezabudnime funkciu importovať:
const {add, testValidity} = require('./script');
test('Zkontroluje jestli jsou 12 a q čísla a vrátí false', () => { expect(testValidity(12, 'q')).toBe(false); })
Integračné testy
Integračná testy fungujú na princípe kombinovanie jednotlivých modulov a testujú ich ako jednu skupinu. Samotné časti kódu môžu fungovať správne, a preto taky prejsť unit testy, ale ak je ich spojenie chybné, vyskytne sa problém, ktorý by práve mal zachytiť tento typ testov.
Vytvoríme preto test integračné funkciu, teda pre addNumbers (). Funkciu si znova importujte. Test bude podobný tomu z funkcie add () a bude vyzerať takto:
test('Přiřadí čísla 2 a 10, zkontroluje validování a propojení, vrátí 15', () => { const number = addNumbers(2, 10); expect(number).toBe(12); })
Vidíme, že sú testy podobné, prečo teda vytvárať integračné testy?
Skúsme napríklad pozmeniť metódu addNumbers()
tak, že
znegujeme počiatočné podmienku:
if (!testValidity) { return add(number1, number2); }
Keď znova spustíme test, obaja unit testy prešli, pretože sa samotnými časťami kódu nie je nič v neporiadku, avšak dané spojenie týchto dvoch funkcií vytvára problémy a na to nás upozorní test integračné.
End-to-End testovanie
Ďalším krokom je End-to-End (E2E) testovanie. Funguje na princípe testovanie celej aplikácie od začiatku do konca. Pre pokračovanie si ale samozrejme budeme musieť pomocou terminálu nainštalovať nové nástroje. Začneme inštalácií nástrojov pre prehliadač Puppeteer:
npm install --save-dev puppeteer
Spoločne s ním sa nám stiahne Chromium. Tomuto testovanie sa taky hovorí "testovanie grafického užívateľského rozhrania" a to z toho dôvodu, že náš test automaticky vykoná to, čo by vykonal používateľ. V súbore s našimi testami musíme importovať samotný Puppeteer:
const puppeteer = require('puppeteer');
Vytvoríme si nový test, tentoraz asynchrónne:
test('Napíše 20 a 10, stiskne tlačítko', async () => { })
Ako prvý musíme otvoriť samotný webový prehliadač. Na to nám bude slúžiť metóda launch (). Môžeme prehliadači nastaviť aj argumenty:
const browser = await puppeteer.launch({ args: ['--window-size=1920,1080'], headless: false, slowMo: 80 });
Ďalej príde otvorenie stránky a premiestnenie sa na danú URL. K tomu máme metódy NEWPAGE () a goto (). Všetko samozrejme stále asynchrónne:
const page = await browser.newPage(); await page.goto('file:///C:/Users/Filip/Documents/ITNETWORK_debugging_Testing/index.html');
URL si musíte napísať vlastnú. Ako posledný krok bude definícia, čo sa má v prehliadači robiť. Zrekapitulujme si to: užívateľ klikne na prvé políčko, napíše číslo, to isté urobí s políčkom druhým a stlačí tlačidlo. Poďme si to teda napísať:
await page.click('input#a'); await page.type('input#a', '20'); await page.click('input#b'); await page.type('input#b', '10'); await page.click('input#button');
Celá funkcia bude vyzerať nasledovne:
test('Napíše 20 a 10, stiskne tlačítko', async () => { const browser = await puppeteer.launch({ args: ['--window-size=1920,1080'], headless: false, slowMo: 80 }); const page = await browser.newPage(); await page.goto('file:///C:/Users/Filip/Documents/ITNETWORK_debugging_Testing/index.html'); await page.click('input#a'); await page.type('input#a', '20'); await page.click('input#b'); await page.type('input#b', '10'); await page.click('input#button'); })
Testy pomocou príkazu npm test
spustí. Mal by sa nám otvoriť
nový webový prehliadač a program automaticky zadať hodnoty. V prípade, že
vám niečo nefunguje, skúste znova nainštalovať Jest, prípadne v
script.js zmazať prvý riadok require, ak sa tu nachádza.
Správanie môže byť na každom počítači trochu iné, je potrebné čítať
ako terminál, tak error v konzole.
Touto témou ukončíme dnešnú lekciu. Ak sa chcete dozvedieť viac o testovaní, odporúčam si prejsť kurz Testovanie v JavaScripte.