Testovanie v JavaScripte pre začiatočníkov
03/2022 / Milan Herda / perunhq.org
Časť 1
Obsah
- Úvod k testovaniu
- Druhy testov v rýchlosti
- Jest - konfigurácia
- Vitest - konfigurácia
Akým spôsobom testujete urobené zmeny?

Testujete celú aplikáciu alebo len zmenené časti?
Má manažment dôveru vo váš kód?

Sadol by si váš manažér do lietadla, ktorého systémy ste programovali vy?
Sadli by ste si vy do takého lietadla?

Automatizované testy
Napísaný test je jediný dôkaz, že ste si svoj kód vyskúšali

Napísaný test ochráni váš kód pred chybou v budúcnosti

Ako vyzerá typický test?
- pripraví si prostredie
- urobí nejakú akciu
- skontroluje výsledok akcie (urobí aserciu)
- arrange
- act
- assert
- given
- when
- then
Čo by mal každý test spĺňať?
- je opakovateľný
- nezávislý na ostatných testoch
- neovplyvňuje iné testy
Druhy testov
* zjednodušene
Akceptačný test
- aplikácia sa testuje v celku
- test navštívi stránku aplikácie
- urobí nejakú akciu
- a skontroluje, či stránka vyzerá tak, ako by mala
Druhy testov
Integračný test
- testuje spoluprácu viacerých jednotiek kódu
- typicky spolupráca viacerých funkcií/modulov/tried
- napr. spolupráca komponentu a prekladov/storu/API...
Druhy testov

Unit test
- testuje jednu jednotku kódu (funkcia/modul/komponent)
- v absolútnej izolácii
Druhy testov

Príklady
Stiahnite si zdrojáky pre príklad:
Jest
Najrozšírenejší testovací framework pre JavaScript.
Pre základné fungovanie nepotrebuje konfiguráciu.
Jest - Inštalácia
yarn add -D jest
Jest - Spustenie
yarn jest
Jest po spustení skenuje aktuálny adresár a jeho podadresáre a hľadá súbory s príponou .test.js alebo .test.ts
Konfigurácia
Spustenie v projekte

Jest bez dodatočnej konfigurácie vie pracovať iba s CommonJS modulmi, podporu pre ES6 treba doplniť.
Pridanie podpory pre
ES6 moduly
yarn add -D @babel/core \
@babel/preset-env \
babel-jest
module.exports = {
presets: ['@babel/preset-env'],
};
Súbor babel.config.js:

Pridanie podpory pre aliasované importy
import sum from '@local/es6-alias/sum';
module.exports = {
moduleNameMapper: {
'^@local/(.*)$': '<rootDir>/src/$1',
},
};
Súbor jest.config.js:

Pridanie podpory pre TypeScript
yarn add -D ts-jest ts-node @types/jest
module.exports = {
moduleNameMapper: {
'^@local/(.*)$': '<rootDir>/src/$1',
},
transform: {
'^.+\\.(js|jsx|mjs|cjs)$': 'babel-jest',
'^.+\\.(ts|tsx)$': 'ts-jest',
},
};
Súbor jest.config.js:
{
"compilerOptions": {
"target": "ESNext",
"strict": true,
"esModuleInterop": true,
"jsx": "react-jsx",
"moduleResolution": "node",
"resolveJsonModule": true,
"module": "ESNext"
}
}
Súbor tsconfig.json:

Pridanie podpory pre aliasované importy v TypeScript-e
{
"compilerOptions": {
"target": "ESNext",
"strict": true,
"esModuleInterop": true,
"jsx": "react-jsx",
"paths": {
"@local/*": ["./src/*"]
},
"moduleResolution": "node",
"resolveJsonModule": true,
"module": "ESNext"
}
}
Súbor tsconfig.json:


Keď uz máme TypeScript, nemohli by sme jest.config mať napísaný v TypeScripte?
Mohli, lebo sme nainštalovali ts-node
Premenujeme jest.config.js na jest.config.ts
import { Config } from '@jest/types';
const config: Config.InitialOptions = {
moduleNameMapper: {
'^@local/(.*)$': '<rootDir>/src/$1',
},
transform: {
'^.+\\.(js|jsx|mjs|cjs)$': 'babel-jest',
'^.+\\.(ts|tsx)$': 'ts-jest',
},
};
export default config;

Rovnaké aliasy máme definované na dvoch miestach, nevieme to nejako zjednotiť?
import { Config } from '@jest/types';
import { pathsToModuleNameMapper } from 'ts-jest';
import tsconfig from './tsconfig.json';
const config: Config.InitialOptions = {
moduleNameMapper: pathsToModuleNameMapper(
tsconfig.compilerOptions.paths,
{
prefix: '<rootDir>',
}
),
transform: {
'^.+\\.(js|jsx|mjs|cjs)$': 'babel-jest',
'^.+\\.(ts|tsx)$': 'ts-jest',
},
};
export default config;
Vitest
Nový testovací framework pre JavaScript, ktorý rýchlo naberá na popularite a vytláča Jest
- Vychádza z bundlera vite (je rýchly)
- API kompatibilné s Jest-om
- jednoduchá konfigurácia
Vitest - Inštalácia
yarn add -D vitest
Vitest - Spustenie
yarn vitest
Jest po spustení skenuje aktuálny adresár a jeho podadresáre a hľadá súbory s príponou .test.js alebo .test.ts
Automaticky sa spúšťa vo watch móde
Konfigurácia
import { defineConfig } from 'vitest/config';
import path from 'path';
export default defineConfig({
test: {
globals: true,
},
resolve: {
alias: {
'@local': path.resolve(__dirname, 'src'),
},
},
});
Ak existuje súbor vite.config.js (ts), tak ho použije.
Ak nemáte vite projekt, môžete vytvoriť súbor vitest.config.js (ts).


Ďakujem za pozornosť

Otázky?
Záver
Kedy spúšťať testy?
Pri vývoji spúšťame priebežne testy aspoň pre nový kód.
Po dokončení tasku spustíme všetky testy.
Najlepšie je mať testy spúšťané aj v CI pre každý Pull Request a po každom merge-i.
Aké druhy testov by sme mali robiť?
Všetky!


Nespomaľuje písanie testov čas vývoja?
Keď sa s testami začína a všetci sa ich učia, tak áno
Ale
- funkctionalitu treba aj tak otestovať
- počas vývoja sa testuje niekoľkokrát to isté - prečo si to neautomatizovať?
- ako dlho trvá fixovanie bugov, ktoré sa našli v produkcii?
- koľko peňazí stojí chyba nájdená v produkcii?
Písanie testov vedie k tvorbe kvalitnejšieho kódu
Existujúce testy znižujú množstvo chýb v kóde
Vývoj ide rýchlejšie, keď je existujúci kód kvalitnejší a bez chýb

Testovanie v JavaScripte pre začiatočníkov, časť 1
By Milan Herda
Testovanie v JavaScripte pre začiatočníkov, časť 1
Motivácia pre písanie automatizovaných testov, konfigurácia pre Jest a Vitest
- 513