End-to-end testy
Nástroje pro end-to-end testování nám umožňují testovat aplikaci přesně tak, jako by ji používal reálný uživatel. Dělají to tak, že nastartují opravdový prohlížeč, otevřou v něm požadovanou stránku, na které klikají, vyplňují formuláře, apod. Nakonec zjistí, zda se celá aplikace chová správně bez nečekaných překvapení - od back-endu až po front-end, včetně databáze, API. Od začátku do konce, neboli end-to-end.
Jen pro úplnost, pokud byste na to někde narazili, end-to-end testy se někdy označují také jako e2e testy.
Nástrojů pro end-to-end testování opět existuje celá spousta. Z těch nejznámějších je to třeba Cypress nebo aktuálně si velkou popularitu získává Playwright, takže si vše vyzkoušíme právě s ním.
Playwright
Stejně jako předtím Vitest, i Playwright si musíme do našeho projektu nejprve nainstalovat:
npm init playwright@latest
Instalace se nás zeptá na několik otázek:
- Kam chceme umístit testy? → Nechme výchozí složku
test
. - Přidat GitHubActions worksflow? → Prozatím vyberme NE. GitHub Action je téma na celou další lekci.
- Nainstalovat Playwright prohlížeče? → Vyberme ANO.
Playwright nám vytvořil v projektu 2 složky:
tests
, kam budeme dávat svoje skutečné testytests-example
, kde je vzorový soubor se spoustou jednoduchých i komplikovaných testů pro vzorovou aplikaci na webu Playwrightu, ze kterých můžeme čerpat znalosti.
Cokoliv budeme potřebovat, najdeme vždy v dokumentaci Playwright.
Uvidíte, že spoustu věcí budeme dělat stejně nebo velmi podobně jako v případě Vitestu.
Náš první end-to-end test
Testy pro Playwright budeme psát do složky tests
a soubory se opět budou jmenovat *.test.ts
nebo *.spec.ts
. Zoložíme si tedy například soubor first.test.ts
.
Stejně jako u Vitestu si s Playwrightu naimportujeme test
a expect
. Metoda describe
je v Playwrightu součástí objetu test
import { test, expect } from '@playwright/test'
// test suite (skupina testů)
test.describe('Home page', () => {
// test
test('something to test', async ({page}) => {
// assertion
await expect(page).toHaveTitle('Homepage')
})
})
Všimněte si, že funkce, kterou předáváme metodě test
jako druhý argument je asynchronní a jako parametr dostává objekt, že kterého si destrukturujeme page
. Přes objekt page
budeme přistupvat ke stránce zobrazené v prohlížeči, který si Playwright spustil na pozadí.
Protože v rámci end-to-end testů testujeme skutečnou stránku ve skutečném prohlížeči, musíme na ní nejprve navigovat, než nad ní budeme provádět jakékoliv testy.
test('something to test', async ({page}) => {
// navigujeme na požadovanou stránku
await page.goto('http://localhost:5173')
// assertion
await expect(page).toHaveTitle('Homepage')
})
Spuštění testu
Samozřejmě to také znamená, že celý projekt musíme před spuštěním testů nejprve spustit přes lokální vývojový server:
npm run dev
Test spustíme pomocí:
npx playwright test
Příkaz si můžeme přidat jako script do package.json
pro snadnější spouštění ve VS Code.
Výsledky testu
Po proběhnutí testu si můžeme zobrazit report:
npx playwright show-report
UI pro playwright
Nebo můžeme testy spustit s parametrem --ui
, který nám spustí grafické rozhraní v prohlížeči, přes které můžeme testy spouštět.
npx playwright test --ui
Další možnost je nainstalovat si rozšíření do VS Code pro spouštění Playwright testů.
Interakce se stránkou
Playwright obsahuje spoustu funkcí pro interakci se stránkou. Můžeme vybírat prvky podle jejich rolí, textu který obsahují, a spoustu dalšího. Playwright umí na prvky klikat, vyplňovat formuláře, apod.
Vybírání prvků
Metoda getByRole
objektu page
vybere na stránce prvek podle jeho účelu. Například chceme zjistit, zda má stránka viditelný nadpis se správným textem:
test('something to test', async ({page}) => {
// navigujeme na požadovanou stránku
await page.goto('http://localhost:5173')
// assertion
await expect(
page.getByRole('heading', {
name: 'Home page'
})
).toBeVisible()
})
Nebo chceme zjistit, že je na stránce odkaz obsahující určitý text:
await expect(
page.getByRole('link', {
name: 'Odkaz'
})
).toBeVisible()
Podobné metodě getByRole
jsou další metody pro vybírání prvků na stránce:
getByText
getByTitle
nebogetByAltText
getByLabel
agetByPlaceholder
pro formuláře
Více v dokumentaci pro lokátory.
getByTestId
Trochu jinak funguje metoda getByTestId
, která vyžaduje, aby měl prvek na sobě data atribut data-testid="whatever"
.
Tato metoda by se měla používat hlavně v případě, že nemůžeme prvek najít podle jeho role nebo textu. Můžeme tak například otestovat, že je danný prvek prázdný:
test('shoping list is empty', async ({page}) => {
await expect(page.getByTestId('shopping-list')).toBeEmpty()
})
Interakce s prvky (klikání, apod.)
Napišme si další test, který otestuje, zda se po kliknutí na odkaz dostaneme na správnou stránku:
test('should redirect on click', async ({page}) => {
await page.goto('http://localhost:5173')
await page.getByRole('link', { name: 'Odkaz' }).click()
// assertion
await expect(page).toHaveTitle('Cilova stranka')
})
Další možnosti jako např. vyplňování formulářových polí najdeme v dokumentaci pro akce.
beforeEach - spouští se před každým testem
Pokud v rámci skupiny testů v každém testu vždy provádíme tu stejnou akci, např. jdeme na jednu konkrétní stránku, můžeme si vše zjednodušit použitím metody beforeEach
, které naš funkcí spustí před každým testem:
test.beforeEach(async ({page}) => {
await page.goto('http://localhost:5173')
})