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?
![](https://s3.amazonaws.com/media-p.slid.es/uploads/689274/images/4499576/testing-in-production.jpeg)
Testujete celú aplikáciu alebo len zmenené časti?
Má manažment dôveru vo váš kód?
![](https://s3.amazonaws.com/media-p.slid.es/uploads/689274/images/4499589/trust-me.jpg)
Sadol by si váš manažér do lietadla, ktorého systémy ste programovali vy?
Sadli by ste si vy do takého lietadla?
![](https://s3.amazonaws.com/media-p.slid.es/uploads/689274/images/4499603/Challenger-604.jpg)
Automatizované testy
Napísaný test je jediný dôkaz, že ste si svoj kód vyskúšali
![](https://s3.amazonaws.com/media-p.slid.es/uploads/689274/images/4499617/well-done.png)
Napísaný test ochráni váš kód pred chybou v budúcnosti
![](https://s3.amazonaws.com/media-p.slid.es/uploads/689274/images/4499611/buffy-the-vampire-slayer-with-cross-300x225.jpg)
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
![](https://s3.amazonaws.com/media-p.slid.es/uploads/689274/images/9609357/two-unit-tests-zero-integration-tests.png)
Unit test
- testuje jednu jednotku kódu (funkcia/modul/komponent)
- v absolútnej izolácii
Druhy testov
![](https://media3.giphy.com/media/VldGsyiAmMW9a/giphy.gif)
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
![](https://s3.amazonaws.com/media-p.slid.es/uploads/689274/images/9516266/jest-01.png)
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:
![](https://s3.amazonaws.com/media-p.slid.es/uploads/689274/images/9516355/jest-es6.png)
Pridanie podpory pre aliasované importy
import sum from '@local/es6-alias/sum';
module.exports = {
moduleNameMapper: {
'^@local/(.*)$': '<rootDir>/src/$1',
},
};
Súbor jest.config.js:
![](https://s3.amazonaws.com/media-p.slid.es/uploads/689274/images/9516383/jest-es6-alias.png)
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:
![](https://s3.amazonaws.com/media-p.slid.es/uploads/689274/images/9609196/Untitled.png)
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:
![](https://s3.amazonaws.com/media-p.slid.es/uploads/689274/images/9609242/done.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/689274/images/4495067/question.png)
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;
![](https://s3.amazonaws.com/media-p.slid.es/uploads/689274/images/4495067/question.png)
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).
![](https://s3.amazonaws.com/media-p.slid.es/uploads/689274/images/9609349/vitest.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/689274/images/9558573/rage.jpg)
Ďakujem za pozornosť
![](https://s3.amazonaws.com/media-p.slid.es/uploads/689274/images/4495067/question.png)
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!
![](https://s3.amazonaws.com/media-p.slid.es/uploads/689274/images/4495143/passing-unit-tests.jpg)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/689274/images/4499661/2-unit-tests-o-integration-tests-.png)
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
![](https://s3.amazonaws.com/media-p.slid.es/uploads/689274/images/4495057/true-story.png)
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
- 438