Je hebt het ding gebouwd. Je hebt erdoorheen geklikt. De knop werkte, het record werd opgeslagen, het dashboard werd bijgewerkt. Je voelt je er goed bij.
Maar jij hebt die code niet geschreven, en als je eerlijk bent, heb je die waarschijnlijk ook niet gelezen. Wat je dus eigenlijk weet is: het werkte één keer, voor jou, terwijl je die ene taak deed die je probeerde. Al het andere over of het “werkt” is vertrouwen.
Het happy path is het enige pad dat de meeste mensen testen
Zo ziet het testen van een vibe-coded app er meestal uit: je uploadt één bestand en het wordt verwerkt. Je verstuurt één formulier en het record verschijnt. Je klikt op één knop en de workflow gaat af. Dat is het. Dat is de test.
Het is geen luiheid. Het is de natuurlijke grens van handmatig testen door iemand die de onderliggende logica niet heeft geschreven. Je kunt alleen bedenken te testen wat je je kunt voorstellen dat misgaat, en als je de code niet kunt lezen, test je de demo, niet het systeem. Het happy path is het enige pad waarvoor de AI met zekerheid heeft geoptimaliseerd, omdat dat het scenario in de prompt was dat de app om te beginnen opleverde.
Het probleem is dat echt gebruik niet op het happy path blijft. Echte gebruikers dubbelklikken. Ze openen twee tabbladen. Ze drukken op terug en versturen opnieuw. Niets daarvan komt naar boven wanneer jij, de bouwer, één keer zorgvuldig door je eigen app klikt, in de volgorde die je verwacht.
Concurrency is waar het echt misgaat
Het duidelijkste voorbeeld is concurrency, en dat is oprecht moeilijk om handmatig te testen, ook als je precies weet waar je op moet letten.
Stel je een op credits gebaseerde functie voor: een gebruiker start een proces, het kost credits, en een saldocontrole zou hem moeten blokkeren zodra het saldo op is. Stel je nu voor dat diezelfde gebruiker vijf tabbladen opent en binnen dezelfde seconde vijf processen start, voordat de eerste factureringscontrole klaar is. Als de logica van ‘controleren en dan afschrijven’ niet is gebouwd om die overlap te verwerken, kunnen alle vijf processen de saldocontrole passeren voordat een van hen een afschrijving registreert. Het resultaat is een gebruiker die processen draait die hij niet kan betalen, een creditsaldo dat negatief wordt, en een accountstatus die nu fout is op een manier die niemand had gepland.
Dat vang je niet door één keer op een knop te klikken. Je zou moeten bedenken om vijf tabbladen te openen, de klikken te timen zodat ze binnen dezelfde fractie van een seconde vallen, en te weten dat ‘saldo controleren’ en ‘saldo afschrijven’ twee afzonderlijke stappen zijn die elkaar kunnen overlappen. Dat is geen testomissie. Het is een categorie bugs die handmatig, één-voor-één klikken structureel niet kan vinden, omdat de bug alleen bestaat wanneer meerdere dingen tegelijk gebeuren, en iemand die alleen test kan die situatie niet makkelijk met opzet creëren, laat staan herhalen.
Dit is precies het soort edge case dat onderzoek naar AI-gegenereerde apps aanmerkt als het faalmodel waar niemand rekening mee houdt: AI bouwt paden voor het specifieke succesvolle scenario waarnaar werd gevraagd, niet voor gelijktijdige bewerkingen, dubbele klikken, of timinggaten tussen stappen. En omdat de resulterende corruptie geen foutmelding geeft, blijft die gewoon stilletjes liggen totdat weken later een rapport of een saldo er verkeerd uitziet.
Waarom bijna niemand de tests schrijft die dit zouden opvangen
De eerlijke oplossing voor dit soort bug is geautomatiseerd testen: unittests, integratietests, iets dat vijf gelijktijdige verzoeken kan simuleren en het resultaat mechanisch kan controleren, in plaats van te vertrouwen op de verbeelding en het geduld van een mens. Geautomatiseerde tests worden niet moe, vergeten geen edge case, en kunnen na elke wijziging opnieuw worden uitgevoerd om te controleren of iets dat je maandag hebt opgelost dinsdag niet weer stuk is.
In de praktijk hebben vibe coders dit bijna nooit. Een testsuite schrijven is op zichzelf een technische vaardigheid, aantoonbaar een moeilijkere dan het schrijven van de app zelf, omdat het redeneren over faalmodi vereist in plaats van alleen dat de functie werkt. Een AI-agent kan tests schrijven als je erom vraagt, maar iemand moet nog steeds weten dat hij moet vragen, begrijpen wat de tests daadwerkelijk controleren, en ze bijhouden terwijl de app eronder verandert. Voor een niet-technische bouwer die op een dinsdagmiddag een klantportaal lanceert, is dat een stap te ver, en zelfs technische bouwers die snel vibe-coden stoppen zelden om testdekking te schrijven voor code die ze toch met de volgende prompt gaan vervangen.
De realistische staat van testen bij de meeste vibe-coded apps is dus: één happy-path doorklik, eenmalig gedaan, door de persoon die het minst is toegerust om te gokken wat er mis kan gaan. Dat is de vertrouwenskloof. Je verifieert niet dat de app werkt. Je hoopt dat het zo is, gebaseerd op dat ene wat je hebt geprobeerd.
Wat ‘visuele zekerheid’ eigenlijk betekent
Er is een echt alternatief voor hopen, en het is niet “leer testsuites schrijven”. Het is het bouwen van de risicovolle onderdelen op een fundament waar de logica niet om te beginnen verborgen is.
Visuele zekerheid betekent dat je een instellingenpaneel kunt openen en precies kunt zien welke gebruikersgroep een record kan bekijken, precies welk filter een blok toepast op een gegevensbron, en precies wat een workflow stap voor stap doet, in volgorde, zonder een regel gegenereerde code te lezen. Je test geen gedrag om de regel erachter af te leiden. Je leest de regel direct.
Dit is het belangrijkst voor de categorieën waar de vertrouwenskloof het duurst is: factureringslogica, rechten, en alles met gelijktijdige gebruikers. Een platform zoals Softr pakt dit aan door rechten, datarestricties en workflowstappen te bewaren als visuele, inspecteerbare configuratie in plaats van AI-gegenereerde code die je regel voor regel zou moeten controleren om te kunnen vertrouwen. Als je wilt weten of een klant de records van een andere klant kan zien, open je de datarestrictieregel en lees je die. Je hoeft niet vijf gelijktijdige logins te simuleren en te hopen dat de AI de race condition correct heeft afgehandeld, want de eigen, geteste infrastructuur van het platform handhaaft de regel, niet een op maat gemaakte controle die de AI voor jouw specifieke prompt heeft geschreven.
Dat betekent niet dat elke aangepaste functie verdwijnt in een instellingenpaneel. Voor echt aangepaste UI is een vibe-coding-blok dat beperkt is tot één component en verbinding maakt via de bestaande rechten- en datalaag van het platform een heel ander risico dan een hele app aan gegenereerde bedrijfslogica, omdat de schade van ‘de AI had dit ene onderdeel fout’ beperkt is tot één blok, niet het factureringssysteem.
- Open het paneel, lees de regel
- Permissies en databeperkingen zichtbaar
- Workflow-stappen in volgorde getoond
- Platform-infrastructuur dwingt dit af
- Gedrag testen, de verborgen regel afleiden
- Code regel voor regel auditen om deze te vertrouwen
- Vijf logins simuleren voor race conditions
- Maatwerkcontrole geschreven voor één prompt
De keuze waar dit je uiteindelijk mee opzadelt
Als je app een weekendproject is of een prototype waar niemand voor betaalt, breng het dan uit, klik één keer door het happy path, en ga verder. De inzet is precies de inzet van de handmatige test die je hebt uitgevoerd.
Als het een klantportaal is, een boekingssysteem, iets met credits, saldi of rollen, is de eerlijke vraag niet “heb ik dit getest?” Het is “kan ik daadwerkelijk de onderdelen verifiëren die pijn zouden doen als ze fout zijn, of vertrouw ik op het woord van een AI?” Als het antwoord vertrouwen is, is dat dezelfde keuze waarover we eerder hebben geschreven bij het Dag Twee-probleem, en beide paden zijn legitiem, afhankelijk van wie je bent.
Als je code kunt lezen, of bereid bent het te leren, dicht dan de kloof met echte tooling in plaats van met een andere bouwer. Cursor werkt binnen een echte codebase waar je kunt vragen om concurrency-tests en vervolgens kunt lezen wat er terugkomt, en Replit geeft je een cloudomgeving waar het draaien van een testsuite een normaal onderdeel van de workflow is in plaats van een bijzaak. De kloof is in beide gevallen niet de capaciteit van de AI, het is of jij weet dat je om de test moet vragen en kunt beoordelen of die goed is.
Als je dat niet kunt, en je bouwt het soort app waarbij een verkeerd recht of een negatief saldo een echt probleem is, verplaats dan de risicovolle onderdelen naar een fundament waar je de regel leest in plaats van te gokken. Bekijk onze ranglijst voor klantportalen als dat de app is die je daadwerkelijk bouwt, want daar kost een verkeerde gok het meest.