Jak se zbavit nestabilních end-to-end testů jednou provždy?
Martin Topolánek
27/5/2024
Určitě jste se setkali s testy, které běžně projdou, ale občas selžou z neznámého důvodu. Spustíte si tedy ten samý scénář a proběhne bez chyby. V tomto článku vám prozradím, jak s těmito problematickými testy zatočit pomocí správně nastaveného prostředí. Navážeme tak na 5 tipů z minulého článku, které se zaměřovaly na prevenci nestabilních testů. Nyní se podíváme na to, jak je efektivně odhalovat a zbavit se jich jednou provždy.
…
My k nastavení prostředí využijeme emulace. Emulace je možná pomocí devtools-protocol. Tento protokol je vyvíjen speciálně pro prohlížeče, které používají Blink renderovací jádro. Jinými slovy — v prohlížeči Firefox toto fungovat nebude.
V tomto článku budeme pracovat s knihovnou Playwright, který komunikuje s Devtools protokolem skrz třídu CDPSession (Chrome Devtools Protocol Session).
…
Spuštění testů v různých prostředích
Pomocí rozhraní CDPSession můžete provádět jakoukoliv akci, kterou lze provést v DevTools. Můžete si tak nastavit emulaci tiskových stránek, emulaci rozostřeného vidění, aj. Úplnou dokumentaci naleznete na stránkách devtools-protocol.
Prostředí s pomalým internetovým připojením
Testovací scénáře často píšete v optimálním prostředí. Při běžném manuálním testování vaše webová aplikace dostává většinou odezvu z backendu okamžitě. Proto vás při psaní scénářů mnohdy nenapadnou různé skalní případy, ve kterých se aplikace může ocitnout.
Tyto scénáře spadnou jen výjimečně a důvod na první pohled není zřejmý. Příčinu objevíte nejspíš až při detálním zkoumání trace souboru. Abyste se těmto spadnutým testům vyhli, máte možnost spustit si scénář s pomalejším síťovým připojením. Při manuálním testováním byste toho docílili přes DevTools. V záložce Network byste změnili hodnotu z No throttling na hodnotu například Slow 3G.
Nyní si ukážeme, jak toho stejného, lze docílit v chrome instanci, kterou spouští Playwright:
import { chromium } from '@playwright/test'
const NETWORK_CONDITIONS = {
'Slow 3G': {
downloadThroughput: ((500 * 1000) / 8) * 0.8,
uploadThroughput: ((500 * 1000) / 8) * 0.8,
latency: 400 * 5,
offline: false,
},
'Fast 3G': {
downloadThroughput: ((1.6 * 1000 * 1000) / 8) * 0.9,
uploadThroughput: ((750 * 1000) / 8) * 0.9,
latency: 150 * 3.75,
offline: false,
},
}
const browser = await chromium.launch()
const context = await browser.newContext({
viewport: { width: 1600, height: 800 },
baseURL: 'https://google.com/',
})
const page = context.newPage()
const cdpSession = context.newCDPSession(page)
if (process.env.NETWORK_CONDITION) {
await cdpSession.send(
'Network.emulateNetworkConditions',
NETWORK_CONDITIONS[process.env.NETWORK_CONDITION],
)
}
await page.goto('/');
Síťové zpomalení pak můžete ovládat pomocí nastavených env.
Prostředí se sníženým CPU výkonem
Webové aplikace se často chovají jinak v závislosti na rychlosti CPU vašeho počítače. Odezvy z aplikace jsou většinou pomalejší. Pokud však odladíte scénáře pro toto pomalejší prostředí, můžete zvážit i větší pararelizaci vašich testů. Platí, že čím víc pararelně spuštěných testů, tím je větší zátěž na CPU a taky větší spotřeba RAM.
Toho lze opět při manuálním testování docílit přes emulaci v DevTools. CPU můžete totiž ovlivnit v záložce Performance a u CPU byste změnili hodnotu z No throttling na hodnotu například 6x slowdown. Nicméně je důležité mít na paměti, že zpomalení CPU je relativní vůči vašemu procesoru.
Relativní zpomalení vašeho CPU můžete docílit i v Playwright testech:
import { chromium } from '@playwright/test'
const browser = await chromium.launch()
const context = await browser.newContext({
viewport: { width: 1600, height: 800 },
baseURL: 'https://google.com/',
})
const page = await context.newPage()
const cdpSession = context.newCDPSession(page)
if (process.env.THROTTLING_RATE) {
await cdpSession.send(
'Emulation.setCPUThrottlingRate', {
rate: parseInt(process.env.THROTTLING_RATE),
})
}
await page.goto('/');
Zpomalení CPU pak můžete ovládat pomocí nastavených env.
Tip na závěr
Navrhuji spustit si vaši sadu testovacích scénářů proti těmto pomalejším prostředím. Při opravování testů se držte 5 tipů, které jsem zmiňoval v předchozím článku.
Abyste předešli dalším nespolehlivým scénářům, doporučuji každý nový testovací scénář spouštět v těchto pomalejších prostředích. Můžete si napsat pomocný skript pro tento případ:
const execSync = require('child_process').exescSync
const arg = process.argv[2] || ''
execSync('cross-env THROTTLING_RATE=10 yarn test ' + arg, { stdio: [0, 1, 2] })
execSync('cross-env NETWORK_CONDITION="Fast 3G" yarn test ' + arg, {
stdio: [0, 1, 2],
})
Skript pak budete spouštět pomocí tohoto příkazu:
node script.js <cesta-k-souboru>