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

  • 372