Testen wordt nog vaak gezien als een manier om bugs op te sporen. Maar een goede teststrategie gaat over veel meer dan dat. Tests kopen vertrouwen en snelheid: ze helpen teams om sneller te releasen, zonder voortdurend bang te moeten zijn dat een wijziging ergens anders iets stukmaakt.
De vraag is niet “Hoeveel tests hebben we?”, maar vooral: welke testen geven ons het meeste vertrouwen voor de investering die we erin doen?
Dat vertrouwen heeft een prijs, en die prijs stijgt naarmate het proces vordert. Een fout die je tijdens het schrijven van code opmerkt, kost bijna niets om te fixen. Als diezelfde fout pas in productie opduikt, kost deze veel meer tijd, geld en soms reputatie. Dat is het idee achter "shift left": hoe eerder in het proces je een probleem vangt, hoe goedkoper de oplossing.
Scope & doel
Wie over testen wil spreken heeft heel wat vakjargon nodig. Als je wat bekend bent met software-testing ken je vast wel een “unit test” of een “regressietest”. Het probleem blijft vaak dat er veel verwarring bestaat wat nu het verschil is tussen allerlei soorten testen.
Het testjargon dat doorgaans gebruikt wordt bestaat eigenlijk uit twee aparte assen. De ene as beschrijft de scope: hoe groot is het stuk code dat je test?
- Een unit test bekijkt één geïsoleerde functie, zonder afhankelijkheden.
- Een integration test kijkt of meerdere onderdelen goed samenwerken.
- Een end-to-end (e2e) test simuleert de volledige gebruikerservaring, zoals een echte gebruiker de applicatie zou doorlopen.
De andere as beschrijft het doel of moment: waarom of wanneer voer je een test uit? Denk aan…
- een smoke test ("draait het überhaupt?"),
- een regressietest ("is er iets kapot gegaan dat eerder werkte?"), of
- exploratory testing, waarbij iemand actief op zoek gaat naar onverwacht gedrag.
In de praktijk combineer je vaak één term van iedere as. Een "e2e smoke test" bevat dus scope én doel tegelijk.
Nu de verschillende soorten testen een beetje duidelijk zijn valt de volgende vraag: Welke heb je nodig en hoeveel? Er zijn verschillende standpunten, hier even twee populaire: de testpiramide (geïntroduceerd door Mike Cohn, gepopulariseerd door Martin Fowler) plaatst veel snelle, geïsoleerde unit tests aan de basis, met minder, tragere, maar uitgebreidere service- en UI-tests vanboven. Kent C. Dodds stelde daar de ‘testing trophy’ tegenover: een model met meer nadruk op integration tests, omdat die meestal het beste evenwicht bieden tussen snelheid en realistische zekerheid. Onderaan die trofee staat nog een vierde laag die vaak vergeten wordt: static testing, zoals linting, typechecking en vulnerability scanning. Deze laag herkent fouten nog vóór je tests überhaupt draaien.
Kies tools op basis van je context
Het JavaScript-landschap biedt vandaag een grote hoeveelheid testingtools. De beste tool bestaat echter niet.
Bij het maken van je keuze, spelen onder meer volgende factoren een rol:
- ervaring binnen het team;
- de bestaande technische stack en eventuele migratiekosten;
- nieuwe interessante tools;
- hoe goed een tool bij de specifieke use case past.
Voor e2e-tests in een browser zijn Playwright en Cypress de bekendste namen. Voor unit- en integration tests zijn Vitest en Jest de dagelijkse werkpaarden. Static testing leunt op TypeScript en ESLint. En voor teams die specificaties in leesbare taal willen delen met niet-developers, biedt een BDD-laag zoals Cucumber tests de mogelijkheid om tests te schrijven in ‘Given / When / Then’-vorm.
Uiteindelijk blijft het een beslissing die het team samen moet dragen, want vertrouwen in je tests staat of valt met vertrouwen in de keuzes erachter.
100% coverage is geen garantie voor 100% kwaliteit.
Coverage
De metric "hoeveel van je code wordt geraakt door tests" is verleidelijk. Maar 100% coverage is geen garantie voor 100% kwaliteit. Een test kan code uitvoeren zonder daadwerkelijk betekenisvolle scenario's of risico's te controleren. Zo kun je bijvoorbeeld veel code coveren en toch belangrijke edgecases missen.
Neem een simpele discount-functie die bij een prijs boven 100 een korting van 10% toepast. Twee tests die de twee paden van een if-statement raken, geven al 100% coverage. Alleen: is de grenswaarde zelf ooit getest? Wat gebeurt er precies bij een prijs van exact 100? Coverage zegt iets over welke regels code zijn uitgevoerd, niet over welke edge cases daadwerkelijk zijn gecontroleerd.
Wie is verantwoordelijk voor kwaliteit?
Een team bestaat uit meer dan developers en analisten, en kwaliteit is dan ook een taak van het team. Developers schrijven doorgaans de unit- en integration tests die dicht bij de code liggen en snel in de pipeline draaien, omdat zij de interne werking het beste kennen. Een tester of QA denkt vanuit het perspectief van de gebruiker: die doet exploratory testing, let op edge cases en bewaakt regressie. Een test automation engineer bouwt en onderhoudt de e2e-suites, integreert ze in CI/CD en zorgt dat de suite stabiel blijft, de brug tussen developers en QA. En de product owner bewaakt de bedoeling: acceptatiecriteria, prioriteit en risico, en de vraag "is dit wat we wilden?"
Betekent dit dat elk team een aparte QA-rol nodig heeft? Niet per se. Zonder aparte QA dragen developers of de product owner zelf die rol: dat is sneller en flexibeler, maar brengt risico op blinde vlekken met zich mee. Met een dedicated tester in het team krijg je een onafhankelijk paar ogen, tegen de prijs van iets meer heen-en-weer. Welke keuze het beste past, hangt af van factoren als productrisico, teamgrootte, klant- en compliance-eisen en release-frequentie.
Tests onderhouden is minstens zo belangrijk als ze schrijven
Een teststrategie werkt alleen als je tests betrouwbaar blijven. Een testsuite waarin sommige tests wisselend groen of rood zijn - flaky tests - creëert een gevaarlijke gewoonte: "het is toch altijd rood", dus niemand kijkt nog naar de resultaten. Vervolgens worden kapotte tests niet meer gefixt, worden er geen nieuwe tests meer geschreven, en versnelt het verval verder. De les hierin is dus simpel maar belangrijk: kwaliteit is een team-verantwoordelijkheid, niet iets dat je aan het einde van de rit nog even oplapt.
Testen reviewen is het nieuwe schrijven.
Wie test de tests?
Een test-suite kan duizenden testen bevatten, het kan nog steeds voorvallen dat er opeens een bug blijkt te zitten in de code en dat een nieuwe test waar nog niemand aan gedacht had die makkelijk covert. Hoe weet je nu welke testen je nog ontbreekt? Er zijn wel wat manieren om dit te doen, sommige al meer manueel dan andere. Een goede automatische optie is mutation testing, met tools zoals Stryker Mutator. Het idee: als 100% coverage niet garandeert dat je tests ook echt iets controleren, test dan de tests zelf. Stryker introduceert kleine, opzettelijke fouten (mutaties) in je code, zoals een > die een >= wordt, en kijkt of je tests daardoor falen. Als een test faalt, controleert die test daadwerkelijk iets zinvols. Blijft alles groen, dan heb je een blind spot. Zo kan een codebase met 100% coverage toch maar een mutation score van 60% halen: een veel eerlijker signaal over hoe goed je tests echt zijn.
AI handelt het af
Een populaire manier van AI-gebruik door developers is AI-generated testen. De belofte is aantrekkelijk: een hele testsuite in seconden, saaie boilerplate opgevangen, de voor de hand liggende gevallen gedekt. Maar de valkuil is even reëel: AI-tests zijn soms “groen, maar leeg” met asserts die bijna niets controleren. Ze testen wat de code doét, niet wat de code zou moeten doen en kunnen daardoor een bestaande bug stilzwijgend als correct bekrachtigen in plaats van de business requirements te volgen. De conclusie is dan ook: testen reviewen is het nieuwe testen schrijven.
Kortom
Testen koopt snelheid en vertrouwen, geen perfectie. Verschillende rollen in het team vullen elkaar daarbij aan, van developer tot product owner. Coverage-percentages alleen zeggen weinig; gebruik de juiste metrics om echt te weten hoe goed je tests zijn. En met de opkomst van AI geldt meer dan ooit: reviewen is het nieuwe schrijven, ook voor testcode.
Een bewuste teststrategie is dus geen eenmalige keuze, maar een doorlopend gesprek binnen het team over waar risico zit, wie waarvoor verantwoordelijk is, en welke tools en metrics daar het beste bij passen.
.webp)


.png)


