Aktuálně: Postihly zákazy tvou profesi? Poptávka po ajťácích prudce roste, využij slevové akce 30% výuky zdarma!
Pouze tento týden sleva až 80 % na e-learning týkající se PHP
PHP týden

Lekce 6 - Automatické testování v JavaScriptu Nové

V minulé lekci, Debugging ve vývojovém prostředí WebStorm, jsme si řekli něco o debuggingu přímo ve vývojovém prostředí WebStorm.

Rozdíl mezi testováním a debuggováním

Když poprvé slyšíme slovo testování, vybavíme si pravděpodobně proces debuggování, který jsme si popsali doposud. Napsali jsme část kódu a spustili ho, abychom zjistili, jestli dostaneme očekávané výsledky. Ač tohle budeme dělat pořád, existuje možnost, jak tento proces do určité míry automatizovat, a to za použití tzv. unit testů. Již od názvu vypovídá, že vezmeme oddělitelnou část kódu a otestujeme, jestli vrací očekávaný výsledek. Dobrý důvod k tomu psát testy je ten, že okamžitě vidíme dopad nového kódu na funkcionalitu. Samozřejmě i unit testy mají svoje místo. Bylo by zbytečné je použít u aplikace o pár řádcích, ovšem ve větším a obsáhlejším projektu nám mohou zpříjemnit život. Popíšeme si také testy integrační a princip testování end-to-end.

Využijeme kódu pro sčítání dvou čísel, zvlášť upraveného pro úč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

Prvně potřebujeme něco, co nám testy umí spustit a zobrazit nám výsledky. K tomuto využijeme populární knihovnu Jest. V tomto článku budu opět pracovat s vývojovým prostředím Visual Studio Code. Pomocí něho Jest nainstalujeme využitím terminálu, který lze zobrazit klávesovou zkratkou Ctrl + ;. Do terminálu napíšeme npm install --save-dev jest a počkáme na dokončení procesu.

Psaní testů

Ukážeme si jednoduchý příklad unit testu, a to na funkci add(number1, number2). Abychom mohli začít testovat, musíme si vytvořit nový soubor ve stejném adresáři, jako je náš skript script.js. Soubor pojmenujeme stejně, akorát k němu přidáme koncovku čili script.test.js. Jest podle koncovky automaticky rozezná, že se jedná o soubor pro testy. Prvně funkci musíme importovat:

const {add} = require('./script');

Jako další využijeme 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í:

test('sečte 5 a 10 má se rovnat 15', () => {

});

V těle funkce si vytvoříme konstantu, která uloží součet dvou čísel za pomocí naší funkce add():

const number = add(5, 10);

Předpokládáme, že se výstup bude rovnat číslu 15, pro to využijeme importovanou funkci expect(), která v parametru bere hodnotu, která se má porovnat, v našem případě konstanta number. Na tuto funkci můžeme dále zavolat funkce k otestování, jestli je hodnota číslo, porovnat ji, zjistit, jestli je definovaná a mnoho dalšího. My využijeme funkci toBe(), která jako parametr bere očekávaný výstup. Celý řádek bude tedy vypadat následovně:

expect(number).toBe(15);

Celá funkce je tedy taková:

test('sečte 5 a 10 má se rovnat 15', () => {
    const number = add(5, 10);
    expect(number).toBe(15);
});

Spouštění testů

Jako část nastavení si vytvoříme soubor package.json a vložíme do něho následující řádky:

{
"scripts": {
    "test": "jest"
  }
}
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

To nám umožní testy spouštět přímo v terminálu. To uděláme pomocí příkazu npm run test. Pokud se vše provedlo tak jak mělo, náš test se provedl úspěšně:

test_uspesny

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

function add(number1, number2) {
    return number1 + number2 + 1;
}

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

test_neuspesny

Pro jednu funkci samozřejmě lze psát více testů. Mohli bychom testovat, jestli je výstup číslo či zabránit falešně pozitivnímu testu sčítáním dvou jiných čísel.

Přidat si můžeme i test pro metodu testValidity(). Nezapomeňme funkci importovat:

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 principu kombinování jednotlivých modulů a testují je jako jednu skupinu. Samotné části kódu mohou fungovat správně, a proto taky projít unit testy, ovšem pokud je jejich spojení chybné, vyskytne se problém, který by právě měl zachytit tento typ testů.

Vytvoříme proto test integrační funkci, tedy pro addNumbers(). Funkci si znova importujte. Test bude podobný tomu z funkce add() a bude vypadat 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 jsou testy podobné, proč teda vytvářet integrační testy? Zkusme například pozměnit metodu addNumbers() tak, že znegujeme počáteční podmínku:

if (!testValidity) {
    return add(number1, number2);
}

Když znova spustíme testy, oba unit testy prošly, protože se samotnými částmi kódu není nic v nepořádku, ovšem dané spojení těchto dvou funkcí vytváří problémy a na to nás upozorní test integrační.

End-to-End testování

Dalším krokem je End-to-End (E2E) testování. Funguje na principu testování celé aplikace od začátku do konce. Pro pokračování si ale ovšem budeme muset pomocí terminálu nainstalovat nové nástroje.

Instalace nástrojů

Začneme instalací nástrojů pro prohlížeč Puppeteer:

npm install --save-dev puppeteer

Společně s ním se nám stáhne Chromium. Tomuto testování se taky říká „testování grafického uživatelského rozhrání“ a to z toho důvodu, že náš test automaticky provede to, co by provedl uživatel. V souboru s našimi testy musíme importovat samotný Puppeteer:

const puppeteer = require('puppeteer');

Vytvoříme si nový test, tentokrát asynchronní:

test('Napíše 20 a 10, stiskne tlačítko', async () => {

})

Jako první musíme otevřít samotný webový prohlížeč. Na to nám bude sloužit metoda launch(). Můžeme prohlížeči nastavit i argumenty:

const browser = await puppeteer.launch({
    args: ['--window-size=1920,1080'],
    headless: false,
    slowMo: 80
});

Dále přijde otevření stránky a přemístění se na danou URL. K tomu máme metody newPage() a goto(). Všechno samozřejmě pořád asynchronně:

const page = await browser.newPage();
await page.goto('file:///C:/Users/Filip/Documents/ITNETWORK_debugging_Testing/index.html');

URL si musíte napsat vlastní. Jako poslední krok bude definice, co se má v prohlížeči dělat. Zrekapitulujme si to: uživatel klikne na první políčko, napíše číslo, to samé provede s políčkem druhým a stiskne tlačítko. Pojďme si to tedy napsat:

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á funkce bude vypadat následovně:

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 pomocí příkazu npm test spusťme. Měl by se nám otevřít nový webový prohlížeč a program automaticky zadat hodnoty. V případě, že vám něco nefunguje, zkuste znova nainstalovat Jest, popřípadě ve script.js smazat první řádek require, pokud se zde nachází. Chování může být na každém počítači trochu jiné, je nutné číst jak terminál, tak errory v konzoli.

Tímto tématem ukončíme dnešní lekci. Pokud se chcete dozvědět více o testování, doporučuji si projít kurz Testování v JavaScriptu.


 

Předchozí článek
Debugging ve vývojovém prostředí WebStorm
Všechny články v sekci
Debugging
Článek pro vás napsal Filip Zeman
Avatar
Jak se ti líbí článek?
Ještě nikdo nehodnotil, buď první!
Autor se věnuje vývoji aplikací v jazyce C# jak už ve sféře desktopové, tak mobilní či herní. Jako mladý člověk s nadšením sleduje nové technologie a postupy.
Aktivity (3)

 

 

Komentáře

Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zatím nikdo nevložil komentář - buď první!