Storybook 8: komponentų testavimas

Kas naujo atneša Storybook 8 versija

Jei dirbate su React, Vue ar bet kuria kita modernia JavaScript biblioteka, tikriausiai jau girdėjote apie Storybook. Ši įrankių platforma tapo neatsiejama komponentų kūrimo dalimi daugelyje projektų. O Storybook 8 versija atneša tikrai reikšmingų pokyčių, ypač komponentų testavimo srityje.

Pirmiausia verta paminėti, kad Storybook 8 iš esmės pertvarkė savo architektūrą. Komanda atsisakė kai kurių senų priklausomybių ir optimizavo veikimą taip, kad projekto paleidimas tapo ženkliai greitesnis. Bet tai tik ledkalnio viršūnė – tikrasis žaidimo keitėjas yra naujas požiūris į komponentų testavimą.

Anksčiau, jei norėjote testuoti komponentus Storybook aplinkoje, turėjote naudoti papildomus įskiepius ir konfigūracijas. Dabar viskas integruota daug glaudžiau, o testavimo galimybės tapo natūralia Storybook ekosistemos dalimi. Tai reiškia, kad galite rašyti testus tiesiogiai savo story failuose, naudodami tą pačią aplinką, kurioje kuriate ir dokumentuojate komponentus.

Kodėl komponentų testavimas Storybook aplinkoje turi prasmę

Daugelis kūrėjų vis dar testuoja komponentus tradiciniais būdais – naudodami Jest, React Testing Library ar panašius įrankius. Ir tai puikiai veikia! Bet štai problema: jūsų testai vyksta vienoje aplinkoje, o komponentų kūrimas ir vizualizacija – kitoje. Tai sukuria tam tikrą atskirtį tarp to, ką matote naršyklėje, ir to, ką testuojate.

Storybook 8 siūlo kitokį požiūrį. Kadangi jūsų komponentai jau yra aprašyti kaip stories, kodėl nepaversti tų pačių stories testais? Tai ne tik sumažina kodo dubliavimąsi, bet ir užtikrina, kad testuojate tiksliai tai, ką matote dokumentacijoje.

Pavyzdžiui, jei turite Button komponentą su skirtingomis būsenomis (primary, secondary, disabled), jūsų stories jau aprašo visas šias variacijas. Dabar galite tiesiogiai ant tų stories užrašyti testus, kurie patikrina, ar komponentas teisingai reaguoja į paspaudimus, ar teisingai pritaiko stilius, ar disabled būsena tikrai neleidžia sąveikos.

Kaip pradėti testuoti komponentus su Storybook 8

Pirmas žingsnis – įsitikinkite, kad turite naujausią Storybook versiją. Jei atnaujinate iš senesnės versijos, rekomenduoju naudoti automatinį migracijos įrankį:

npx storybook@latest upgrade

Kai turite Storybook 8, jums reikės įdiegti kelis papildomus paketus testavimui:

npm install --save-dev @storybook/test @storybook/addon-interactions

Šie paketai suteikia jums visus reikalingus įrankius interaktyvių testų rašymui. @storybook/test paketas iš esmės yra Testing Library ir Vitest funkcijų rinkinys, pritaikytas darbui su Storybook. O @storybook/addon-interactions leidžia matyti testų vykdymą realiu laiku Storybook sąsajoje.

Dabar galite pradėti rašyti testus tiesiogiai savo story failuose. Štai paprastas pavyzdys:


import { Button } from './Button';
import { expect, userEvent, within } from '@storybook/test';

export default {
component: Button,
title: 'Components/Button'
};

export const Primary = {
args: {
label: 'Click me',
variant: 'primary'
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const button = canvas.getByRole('button');

await expect(button).toBeInTheDocument();
await userEvent.click(button);
await expect(button).toHaveClass('button--primary');
}
};

Play funkcija – jūsų naujas geriausias draugas

Pagrindinis dalykas, kurį turite suprasti apie Storybook 8 testavimą, yra play funkcija. Tai speciali funkcija, kuri vykdoma po to, kai komponentas yra atvaizduotas. Čia ir rašote savo testus.

Play funkcija gauna kelis naudingus parametrus. canvasElement – tai DOM elementas, kuriame atvaizduotas jūsų komponentas. Naudodami within funkciją, galite apriboti savo užklausas tik šiam elementui, kas ypač naudinga, kai turite daug komponentų viename puslapyje.

Kas įdomu – play funkcijos vykdomos ne tik Storybook sąsajoje. Galite jas paleisti kaip įprastus testus naudodami test-runner įrankį. Tai reiškia, kad tie patys testai, kuriuos matote veikiant naršyklėje, gali būti automatiškai vykdomi jūsų CI/CD pipeline.

Štai sudėtingesnis pavyzdys, kuris demonstruoja formų testavimą:


export const LoginForm = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);

const emailInput = canvas.getByLabelText('Email');
const passwordInput = canvas.getByLabelText('Password');
const submitButton = canvas.getByRole('button', { name: /submit/i });

await userEvent.type(emailInput, '[email protected]');
await userEvent.type(passwordInput, 'password123');
await userEvent.click(submitButton);

await expect(canvas.getByText('Login successful')).toBeInTheDocument();
}
};

Interakcijų stebėjimas realiuoju laiku

Vienas iš gražiausių Storybook 8 testavimo aspektų yra tai, kad galite stebėti testų vykdymą tiesiogiai naršyklėje. Kai įjungiate Interactions addon, matote kiekvieną veiksmą, kurį atlieka jūsų testai – kiekvieną paspaudimą, kiekvieną įvestą simbolį, kiekvieną patikrinimą.

Tai neįtikėtinai naudinga debuginant. Vietoj to, kad spėliočiau, kodėl testas nepavyko, galite tiesiog pažiūrėti į Interactions panelę ir pamatyti tiksliai, kuriame žingsnyje įvyko klaida. Matote, kokios buvo elementų būsenos, kokie buvo jų atributai, ką grąžino užklausos.

Be to, galite pristabdyti testų vykdymą bet kuriame taške ir patys pabandyti sąveikauti su komponentu. Tai leidžia eksperimentuoti ir suprasti, kodėl tam tikri scenarijai veikia ar neveikia taip, kaip tikėjotės.

Integravimas su CI/CD procesais

Gerai, taigi turite gražius interaktyvius testus Storybook sąsajoje. Bet kaip juos paleisti automatiškai kiekviename commit’e ar pull request’e? Čia į pagalbą ateina Storybook test-runner.

Test-runner yra atskiras įrankis, kuris gali paleisti visus jūsų Storybook testus headless naršyklėje. Jis naudoja Playwright po gaubtu, todėl testuojate tikroje naršyklės aplinkoje, ne simuliuotoje.

Instaliavimas paprastas:

npm install --save-dev @storybook/test-runner

Tada jūsų package.json galite pridėti scriptą:


"scripts": {
"test-storybook": "test-storybook"
}

Prieš paleidžiant testus, įsitikinkite, kad Storybook serveris veikia. Galite tai padaryti dviem būdais: arba paleisti npm run storybook atskirame terminale, arba sukurti statinę Storybook versiją su npm run build-storybook ir nurodyti test-runner’iui naudoti ją.

CI/CD aplinkoje paprastai geriau naudoti statinę versiją. Štai kaip tai galėtų atrodyti GitHub Actions:


- name: Install dependencies
run: npm ci

- name: Build Storybook
run: npm run build-storybook

- name: Run Storybook tests
run: npm run test-storybook -- --url file://$(pwd)/storybook-static

Praktiniai patarimai ir geriausia praktika

Po kelių mėnesių darbo su Storybook 8 testavimu, galiu pasidalinti keliais patarimais, kurie gali sutaupyti jums laiko ir nervų.

Pirma, nelaikykite play funkcijų kaip vienintelio testavimo šaltinio. Jos puikiai tinka UI sąveikos testavimui, bet sudėtingesnei logikai vis tiek geriau naudoti tradicinius unit testus. Play funkcijos – tai daugiau integration testai, kurie patikrina, ar jūsų komponentas teisingai veikia vartotojo perspektyvoje.

Antra, struktūrizuokite savo stories taip, kad kiekviena story reprezentuotų konkretų naudojimo atvejį. Vietoj vienos didelės story su daugybe testų, geriau turėti kelias mažesnes stories, kiekviena su savo testu. Tai padaro testus lengviau skaitomus ir prižiūrimus.

Trečia, naudokite step funkciją iš @storybook/test paketo, kad suskirstytumėte sudėtingus testus į loginius žingsnius:


import { expect, userEvent, within, step } from '@storybook/test';

export const ComplexFlow = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);

await step('Fill in user details', async () => {
await userEvent.type(canvas.getByLabelText('Name'), 'John Doe');
await userEvent.type(canvas.getByLabelText('Email'), '[email protected]');
});

await step('Submit form', async () => {
await userEvent.click(canvas.getByRole('button', { name: /submit/i }));
});

await step('Verify success message', async () => {
await expect(canvas.getByText('Success!')).toBeInTheDocument();
});
}
};

Ketvirta, atminkite, kad play funkcijos yra asinchroninės. Visada naudokite await su userEvent funkcijomis ir expect tvirtinimais. Tai užtikrina, kad kiekvienas veiksmas bus baigtas prieš pradedant kitą.

Penkta, jei testuojate komponentus, kurie daro API užklausas, naudokite mock’us. Storybook puikiai integruojasi su MSW (Mock Service Worker), kuris leidžia interceptuoti network užklausas ir grąžinti fake duomenis. Tai užtikrina, kad jūsų testai bus stabilūs ir nepriklausys nuo išorinių servisų.

Kai viskas susideda į vieną vietą

Storybook 8 komponentų testavimas nėra revoliucija, bet evoliucija. Tai natūralus žingsnis į priekį, kai kūrimas, dokumentavimas ir testavimas susilieja į vieną sklandų procesą. Nebereikia šokinėti tarp skirtingų įrankių ir aplinkų – viskas vyksta ten, kur kuriate savo komponentus.

Ar tai reiškia, kad turėtumėte visiškai atsisakyti tradicinių testų? Tikrai ne. Bet jei jau naudojate Storybook dokumentacijai, pridėti interaktyvius testus yra logiškas žingsnis, kuris suteikia papildomos vertės be didelio papildomo darbo. Jūsų stories tampa ne tik dokumentacija, bet ir gyvais testais, kurie užtikrina, kad komponentai veikia taip, kaip aprašyta.

Pradėkite nuo paprastų dalykų – pridėkite kelis pagrindinius testus savo svarbiausių komponentų stories. Pažiūrėkite, kaip jie veikia Interactions panelėje. Integruokite test-runner į savo CI procesą. Ir pamažu pastebėsite, kad jūsų komponentų biblioteka tampa ne tik gražesnė, bet ir patikimesnė.

Daugiau

Kuo profesionali krovinių pervežimo įmonė skiriasi nuo pavienių vežėjų