Engineering Design
Testing Strategy

Testing Strategy

Test Pyramid

LayerToolCoverage targetRuns in
Unit testsJest80% minimumCI — every push
Integration — backendJest + SupertestAll 12 custom endpointsCI — every push
API contractNewman (Postman collections)Full collection against staging DBStaging deploy
ComponentStorybook + ChromaticAll ui/ componentsOn PR
E2EPlaywrightAll 6 critical journeysStaging deploy
SmokePlaywright (subset)5–10 pathsPost-prod deploy

Critical E2E Journeys (Playwright)

  1. Happy path: invite → register → browse → add to cart → checkout → download
  2. Auth guards: protected routes redirect unauthenticated users to /login
  3. Download validation: valid token → file; expired token → 410; wrong customer → 403
  4. Stripe payment failure: order stays failed, no download links created
  5. Invite expiry: expired token shows correct error, no account created
  6. Rate limiting: 6 failed logins → account locked message shown

Newman — API Contract Testing

Postman collection covers all 12 custom endpoints. Newman runs it against a seeded staging database on every staging deploy.

# Install Newman
npm install -g newman
 
# Run collection
newman run ./tests/api/vespertene-shop.postman_collection.json \
  --environment ./tests/api/staging.postman_environment.json \
  --reporters cli,junit \
  --reporter-junit-export ./test-results/newman.xml

Test Data Management

  • Backend: seed script at src/scripts/seed.ts — creates test products, a test customer, promo codes
  • Playwright: beforeAll hooks create test data via API, afterAll cleans up
  • Never hard-code UUIDs in tests — fetch them from seed output
  • Staging DB reset: npm run db:reset:staging before Newman runs

Download System — Required Test Cases

ScenarioExpectedTest type
Valid token, within limit302 → presigned URL, count incrementedIntegration + E2E
Expired token410 DOWNLOAD_EXPIREDIntegration
Exhausted token (3/3)410 DOWNLOAD_LIMIT_REACHEDIntegration
Wrong customer's token403 FORBIDDENIntegration (IDOR test)
Tampered UUID404 NOT_FOUNDIntegration
Duplicate Stripe webhookIdempotent — no second link setIntegration