146 lines
4.8 KiB
Markdown
146 lines
4.8 KiB
Markdown
# 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.
|