IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

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:

test_uspesny - Debugging

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:

test_neuspesny - Debugging

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.


 

Predchádzajúci článok
Debugging vo vývojovom prostredí webstore
Všetky články v sekcii
Debugging
Článok pre vás napísal Filip Zeman
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
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