@@ -0,0 +1,145 @@
|
||||
# Teststrategie
|
||||
|
||||
## Doel
|
||||
|
||||
Tests bewijzen dat VacatureRadar veilig herhaalbaar verzamelt, betrouwbare canonieke data maakt, uitlegbaar scoort en zonder externe services blijft functioneren. De standaardtestset is snel, deterministisch en offline.
|
||||
|
||||
## Testpiramide
|
||||
|
||||
### Unit
|
||||
|
||||
Pure functies en begrensde services:
|
||||
|
||||
- URL-validatie en canonicalisatie;
|
||||
- source policy en denylist;
|
||||
- adapterextractie uit fixtures;
|
||||
- HTML-sanitization;
|
||||
- normalisatie van titel, contract, locatie en datums;
|
||||
- feature-extractie, distance fallback en scoring;
|
||||
- AI-schema/parsing/fallback;
|
||||
- profielgewichten en feedbackgrenzen.
|
||||
|
||||
Doel: veel kleine tests, geen echte netwerkcall en alleen database wanneer het objectgedrag zelf wordt getest.
|
||||
|
||||
### Integratie
|
||||
|
||||
Meerdere componenten met testdatabase:
|
||||
|
||||
- raw document → adapter → normalisatie → dedupe → provenance → score;
|
||||
- replay/idempotentie en vacatureversies;
|
||||
- IMAP/e-mailrecording via gesimuleerde berichten;
|
||||
- digest-outbox en mailbackend;
|
||||
- lifecycle en sollicitatiedossier;
|
||||
- Django-views, login, user-scoping en POST-acties;
|
||||
- Celerytasks in eager mode.
|
||||
|
||||
### Security
|
||||
|
||||
Negatieve tests voor trust boundaries:
|
||||
|
||||
- loopback, private, link-local, encoded/credentialed en onverwachte URL's;
|
||||
- redirecthercontrole;
|
||||
- denylistplatformen;
|
||||
- contenttype/grootte;
|
||||
- XSS/sanitization en onveilige links;
|
||||
- prompt-injectionachtige vacaturetekst;
|
||||
- cross-user objecttoegang;
|
||||
- secret-/payloadlekken in foutpaden waar praktisch testbaar.
|
||||
|
||||
### Browser/e2e
|
||||
|
||||
Gepland in backlogtaak `VR-114`. Gebruik een lokale testserver en seeded data, geen live bron. Minimale flows:
|
||||
|
||||
1. aanmelden;
|
||||
2. dashboard openen;
|
||||
3. profiel wijzigen en revisie zien;
|
||||
4. vacature zoeken/openen;
|
||||
5. interessant/verbergen/gesolliciteerd;
|
||||
6. sollicitatiedossier bijwerken;
|
||||
7. bronstatus bekijken;
|
||||
8. toetsenbord- en basisaccessibilityscan.
|
||||
|
||||
Browsertests zijn aanvullend; zij vervangen geen service- of autorisatietests.
|
||||
|
||||
### Release- en deploymenttests
|
||||
|
||||
- Dockerfile buildt zonder ontwikkelbestanden/secrets;
|
||||
- container start als niet-rootgebruiker;
|
||||
- migraties en `collectstatic` slagen;
|
||||
- liveness/readiness reageren correct;
|
||||
- Composeconfiguratie parseert;
|
||||
- PostgreSQL/Redisstack verwerkt één fixture en digest;
|
||||
- back-up en restore zijn op een tijdelijke omgeving getest.
|
||||
|
||||
Deze laag kan in CI of een releasejob draaien zodra een Dockerdaemon beschikbaar is.
|
||||
|
||||
## Fixtures
|
||||
|
||||
Directoryindeling:
|
||||
|
||||
```text
|
||||
fixtures/pages/ HTML/JSON-LD
|
||||
fixtures/feeds/ RSS/Atom/sitemaps
|
||||
fixtures/emails/ RFC822-berichten
|
||||
fixtures/golden/ verwachte gestructureerde output
|
||||
```
|
||||
|
||||
Regels:
|
||||
|
||||
- fictieve werkgevers/personen en `example.*`-domeinen;
|
||||
- alleen het minimum aan vacaturetekst;
|
||||
- geen cookies, tokens, echte Message-ID's of persoonlijke adressen;
|
||||
- bronvariant en doel van fixture in testnaam of korte comment;
|
||||
- grote regressiepayloads waar mogelijk reduceren tot minimale reproducer.
|
||||
|
||||
## Netwerkisolatie
|
||||
|
||||
Geen test mag standaard internet vereisen. Patch `httpx`, DNS-resolutie, IMAP, SMTP en Ollama aan de boundary. Een test die per ongeluk live netwerk gebruikt, is een testfout. Eventuele live smoke-tests krijgen een aparte marker, expliciete environmentflag en draaien nooit in de standaard-CI.
|
||||
|
||||
## Dekkingsbeleid
|
||||
|
||||
`pyproject.toml` vereist minimaal 70% branch-aware totaal. Dekking is een vangnet, geen doel op zich:
|
||||
|
||||
- fetcher, URL-security, policy, sanitization, authscoping en automatische acties: alle belangrijke negatieve paden;
|
||||
- parsers: iedere ondersteunde variant plus malformed/lege input;
|
||||
- scoring/dedupe: beslisdrempels en tie-breakers;
|
||||
- triviale adminregistratie en migratiecode mogen uit de meting blijven.
|
||||
|
||||
Verlaag de drempel niet voor een taak. Voeg tests toe of documenteer en verwijder aantoonbaar dode code.
|
||||
|
||||
## Testdata en tijd
|
||||
|
||||
- Gebruik timezone-aware vaste datums of `timezone.now()` relatief binnen de test.
|
||||
- Vermijd assertions die na middernacht lokale tijd flaken.
|
||||
- Randomized/propertytests gebruiken een vaste seed en melden die bij falen.
|
||||
- Volgorde-onafhankelijkheid: iedere test maakt eigen state via fixtures/factories.
|
||||
|
||||
## Performance
|
||||
|
||||
Voor `NFR-007` komt een reproduceerbaar benchmarkscript in `VR-116` met minstens:
|
||||
|
||||
- 25.000 canonieke vacatures;
|
||||
- meerdere aliassen en scoreruns;
|
||||
- dashboard/list/detailqueries;
|
||||
- importbatch en rescore;
|
||||
- p50/p95, querycount en geheugengebruik.
|
||||
|
||||
Een performanceclaim wordt alleen in documentatie opgenomen met hardwareprofiel, dataset en meetcommando.
|
||||
|
||||
## Uitvoercommando's
|
||||
|
||||
```bash
|
||||
uv run pytest tests/unit
|
||||
uv run pytest tests/integration
|
||||
uv run pytest tests/security
|
||||
uv run pytest --cov=apps --cov=config --cov-report=term-missing
|
||||
./scripts/codex_verify.sh
|
||||
```
|
||||
|
||||
## Bugworkflow
|
||||
|
||||
1. Reproduceer met kleinste betrouwbare fixture/test.
|
||||
2. Laat de test falen op de huidige code.
|
||||
3. Herstel bij de laag waar de regel hoort.
|
||||
4. Draai relevante tests en daarna de volledige gate.
|
||||
5. Werk threat model/runbook bij wanneer het een security- of operationeel defect was.
|
||||
Reference in New Issue
Block a user