Je suite staat op rood, maar niemand kijkt er nog naar om. Dat moment waarop het team besluit het te negeren, is het échte probleem.
Iedereen kent het scenario. De build faalt. Iemand kijkt, haalt de schouders op, en drukt op "rerun". De tweede keer slaagt hij wel. Probleem "opgelost".
Dat moment waarop het team besluit dat rood niet meer betekent dat er iets stuk is, dat is het echte probleem. Niet de falende test. De gewenning eraan.
Een flaky test is een test die soms slaagt en soms faalt, zonder dat de code veranderde. Zelfde input, zelfde omgeving, ander resultaat. Hij detecteert niet altijd hetzelfde gedrag. En dat maakt hem gevaarlijker dan een test die consequent faalt.
Een kapotte test kun je fixen. Een onbetrouwbare test ondermijnt iets fundamentelers: het vertrouwen in je hele suite. Want als deze test soms liegt, welke andere doen dat dan ook?
Flaky tests wekken een vals gevoel van veiligheid. Je suite is groen, dus alles is in orde. Behalve dat een deel van dat groen toeval is. En het omgekeerde is nog erger: teams leren om rood te negeren. "Ah, die is gewoon flaky." Tot de dag dat rood écht rood was.
Wij zien bij klanten hoe dit sluipend gaat. Eerst is het één test. Dan drie. Dan is er een gedeeld begrip in het team dat "de suite altijd wat rood staat". Op dat punt is je vangnet geen vangnet meer, maar decoratie.
De klassieker. De test klikt op een knop voordat de pagina klaar is met laden. Op een snelle machine gaat het goed, op een trage CI-runner niet. Vaste wachttijden (sleep(2)) zijn een pleister die op een dag loslaat.
JJe test is afhankelijk van systemen die buiten de controle van de test liggen: een externe API, een service van een andere applicatie of een gedeelde omgeving. Die is even traag, even down, of geeft net iets anders terug. Je test faalt, maar je code is prima.
Twee tests gebruiken hetzelfde record. De ene wijzigt het, de andere leest het. Draaien ze parallel, dan is de uitkomst een gok. Draaien ze in een andere volgorde, idem.
De testomgeving is net niet gelijk aan productie. Er draait nog iets van gisteren. De cache is niet leeg. De ene runner heeft meer geheugen dan de andere.
De test hangt af van de huidige tijd, willekeurige gegevens of de volgorde waarin tests worden uitgevoerd. Daardoor kan exact dezelfde test verschillende resultaten geven.
Het verschil tussen de twee zit in een paar regels code:
// flaky: gokt hoelang laden duurt
await page.click('#submit');
await page.waitForTimeout(2000);
await expect(page.locator('#confirmation')).toBeVisible();
// stabiel: wacht op de conditie zelf, niet op een gok
await page.click('#submit');
await expect(page.locator('#confirmation')).toBeVisible({ timeout: 10000 });
Op een snelle machine zie je het verschil niet. Op een drukke CI-runner, tijdens honderd parallelle builds, wel — en precies dan wil je dat je test wacht op wat er echt gebeurt, niet op een aanname.
Het belangrijkste is geen techniek, het is een mentaliteitswijziging: behandel een flaky test als een bug. Niet als achtergrondruis, niet als "die doet dat soms". Zet hem op de backlog, geef hem een prioriteit, en fix hem.
Teams die dat doen, hebben een suite waar rood ook echt rood betekent. En dat is uiteindelijk het enige waar het om gaat.
We nemen je testaanpak door en zeggen eerlijk waar de winst zit. En waar niet.
Plan een gesprek