# Testbaarheid en teststrategie ## Huidige toestand De backendfuncties zijn meestal procedureel en krijgen `config` expliciet mee. Dat is een goede basis voor tests. PostgreSQL-invarianten zitten echter in concrete opslagprocedures en er is nog geen projectbrede geautomatiseerde testsuite met tijdelijke database. Versie 0.2.93 introduceert wel tests in `architecture/import.rkt`. Die controleren de manifestset, interne paginalinks, CMap-embeds, unieke node-id's, connector-endpoints en de bronmarkeringen waarmee lokaal gewijzigde importinhoud wordt beschermd. Dit is een begin, geen voldoende dekking van de wiki. ## Testpiramide voor racket-wiki | Laag | Doel | Voorbeelden | | --- | --- | --- | | Pure unit tests | Deterministische omzettingen snel controleren | slugvorming, linkextractie, todoherkenning, markerhashes, TLS-keuze | | Componenttests | Eén module met echte randvoorwaarden | CMap-document laden/bewaren, Markdowntransformaties, requestparsing | | PostgreSQL-integratietests | Transacties en constraints bewijzen | create/update/conflict, historie, aliases, bijlagen, migraties | | HTTP-integratietests | Rollen en API-contracten bewijzen | 401/403/409, CSRF, JSON-vormen, upload/download | | Browser-smoketests | Kritische gebruikerspaden bewijzen | login, split editor, CMap drag/undo/autosave/snapshot, beheer | De meeste varianten horen onderin. Een browsertest is te duur om alle slug- of linkgevallen af te dekken; een pure test kan niet bewijzen dat een SQL-transactie werkelijk atomair is. ## Prioriteit voor regressietests De eerste volwaardige suite moet deze risico's afdekken: 1. twee editors op dezelfde pagina of CMap, waarbij de tweede een 409 krijgt; 2. actuele toestand en onveranderlijke versie worden samen geschreven of samen teruggedraaid; 3. pagina hernoemen behoudt id en maakt een werkende alias; 4. todo- en bijlageindices volgen exact de actuele Markdown; 5. reader, editor en admin kunnen uitsluitend hun toegestane endpoints gebruiken; 6. sessie-, CSRF- en herstelcodes worden correct gevalideerd en ingetrokken; 7. CMap-documenten maken een stabiele load/save-roundtrip; 8. slepen op een sub-CMapframe verplaatst alle afstammelingen, slepen op het hoofdconcept niet; 9. autosave, handmatige save en snapshot krijgen het juiste historische `action` en `summary`; 10. migratie vanaf iedere ondersteunde schemaversie levert dezelfde actuele structuur. ## Tijdelijke PostgreSQL-database Integratietests gebruiken een afzonderlijke database of tijdelijk schema en nooit de ontwikkel- of productiedatabase. Iedere test begint vanuit een bekende migratiestand en ruimt eigen data op. De testconfiguratie komt uit expliciete testomgevingsvariabelen; wachtwoorden worden niet in de repository opgenomen. Een praktische eerste stap is één testdatabase per testrun, met unieke namespace of schema per proces. Tests die locking en conflicts controleren gebruiken twee echte verbindingen. ## Testbare grenzen verbeteren Maak pure omzettingen los van I/O wanneer zij voldoende domeinbetekenis hebben. Voorbeeld: validatie en normalisatie van een paginabewerking kan als pure procedure worden getest; de opslagprocedure gebruikt het resultaat binnen de transactie. Introduceer geen groot mockframework. Gewone procedures en expliciete parameters zijn voldoende. Wanneer tijd of willekeur een test blokkeert, geef een kleine `current-clock`- of token-generatorparameter door op de laag die deze bron bezit. Voor frontendcode zijn browsercomponenttests met een echte DOM geschikter dan het namaken van ieder element. De CMap-adapter moet met een klein vast document getest kunnen worden zonder de hele wiki te starten. ## Contract- en structuurcontroles Naast functionele tests hoort de releasecontrole automatisch te verifiëren: - alle Racket-modules compileren met `raco make`; - `raco test` vindt en draait de tests; - JavaScript kan syntactisch worden geparseerd; - iedere `$("id")`-referentie heeft een overeenkomstig HTML-element; - vertaalkeys die de UI gebruikt bestaan; - alle bestanden in het architectuurmanifest bestaan en verwijzen onderling geldig; - het ZIP-archief bevat geen `wiki-data`, wachtwoorden, tijdelijke bestanden of buildoutput. ## Wanneer is een wijziging klaar? Een bugfix is pas klaar wanneer het oorspronkelijke scenario reproduceerbaar is en de test vóór de fix faalt of aantoonbaar het defecte pad raakt. Een nieuw endpoint heeft minimaal opslag-/domeintests en rol-/CSRF-tests. Een schemawijziging heeft zowel verse-installatie- als upgrademigratietests. Zie [Analyseerbaarheid](racket-wiki:analyseerbaarheid) voor het verzamelen van een minimale reproductie en [Regels bij het coderen](racket-wiki:code-regels) voor testvriendelijke codevormen.