Testing Strategy

How We Test ReviewForest

Test layers aren't isolated — they deliberately overlap at the integration boundary. Only when combined do they guarantee a stable, fully covered system.

Test Environment: Staging → Docker

❌ Before: Staging

DEPRECATED
Shared DB — tests pollute each other's data
Manual testing runs in parallel, causes conflicts
Dirty state from previous test runs
Network latency to remote environment
Hard to reset to a known state
Flaky tests from environment issues, not code bugs
migrate

✓ After: Docker

CURRENT
Fresh DB with seeds on every run — zero shared state
Fully isolated — no conflicts with other processes
Deterministic — same input, same output, every time
Local execution — fast, no network overhead
Seeds as code — versioned, reviewed in MRs
Runs identically in CI and on developer machines

🐳 Docker Compose Test Stack

Isolated network — no internet access. Backend thinks it talks to real APIs, but DNS resolves all external domains to WireMock. Zero code changes required.

Test Runner Playwright
runs in browser
Frontend Vue SPA
build: . (local)
Backend API server
image: registry
MongoDB clean DB
+ seeds
Firebase Emulator auth
local emulator
Stripe Mock payments
stripe/stripe-mock
WireMock DNS proxy for:
Google, Trustpilot, OMR
🔒
Isolated Network — No Internet
network: internal — containers can't reach the internet
DNS aliases — api.google.com → WireMock, api.trustpilot.com → WireMock
Result — backend sends real HTTP requests, WireMock intercepts via DNS. No code changes needed.
docker compose up health checks DB seed run Playwright tear down

System Architecture & Test Coverage

Our Code
Vue SPA local build
Backend API from registry
MongoDB clean + seeded
Firebase Emu / Stripe Mock local
Overlap Zone WireMock proxy
DNS interception
E2E: WireMock intercepts via DNS
Contract: real API calls
Both verify this boundary
Third-Party APIs
Google Reviews, Places
Trustpilot Reviews API
Amazon Product Reviews
OMR Reviews
UI Logic Adapters External APIs
E2E + Mocks
UI → adapters (mocked responses)
Contract
adapters → real APIs
Unit
isolated modules
Combined
✓ FULL COVERAGE — no blind spots

E2E + Mocks

our code works correctly

+

Contract Tests

APIs still match our mocks

=

✓ Full Confidence

stable, fully tested system

⚡ Why the Overlap Matters

E2E Tests

Verify our code from UI to API client layer using mocked responses. Fast, deterministic, run on every PR. If these fail → bug in our code.

Contract Tests

Verify that real APIs still return what our mocks expect. Run daily / pre-release. If these fail → API changed, update fixtures.

The Bridge

Both test layers share the same adapter boundary. Contract tests validate mocks. E2E tests use those mocks. This overlap guarantees no gaps.

E2E + Mocks

on: pull_request
  • User flows: login → dashboard → reviews
  • UI renders data correctly
  • Routing, guards, redirects
  • Error handling (mock 500, timeout, 429)
  • Forms, validation, submit flows
  • State management works correctly

Contract Tests

schedule: daily
  • Response schema hasn't changed
  • Auth / tokens are working
  • Rate limits are handled
  • New or deprecated fields detected
  • Webhook payloads are valid
  • Auto-update fixtures on change

Unit / Component

on: push
  • Data transformation functions
  • Components render correctly
  • Composable logic in isolation
  • Edge cases, boundary values
  • Store mutations and actions
  • Validation and error mapping

Comparison

E2E + Mocks
Contract
Unit
Third-party
Mocked WireMock DNS proxy
Real calls
Not involved
When it fails
Bug in our code
External API changed
Bug in isolated module
Flaky risk
Minimal
Possible
Zero
Trigger
on: pull_request
schedule: daily
on: push
Fixed by
Frontend / Backend devs
Update fixtures + adapters
Module author