Testing Strategy
The Wordloop test pyramid, unit testing, and cross-service system testing.
Testing Strategy
Wordloop utilizes a structured test pyramid that catches domain logical errors instantaneously through unit tests, and integration faults deterministically via Dockerized environments.
The Test Pyramid
- Unit (70%): Pure domain functions. Zero infrastructure dependencies. Executed in milliseconds.
- Integration (20%): Provider layer. Real Postgres, GCS, and PubSub containers via
testcontainers. - System (10%): The entire platform booting concurrently over an emulated network. Driven exclusively via HTTP APIs.
1. Unit & Integration Testing
Backend (Go / Python)
- Domain Layer: Tested purely with input/output assertions, avoiding mocks to ensure high-fidelity domain verification.
- Service/Orchestration: Mocks (
mockeryfor Go, direct overrides for Python) allow testing routing logic without instantiating databases. - Provider Layer: We test against real database instances to guarantee contract fidelity. Testing a Postgres adapter requires a real Postgres container (
testcontainers). Tests execute against a fresh, migrated schema.
Frontend (Next.js / React)
- Focus is exclusively on Component behavior strings and hooks.
- State Consistency: We wrap all asynchronous state updates with
act(...)to prevent testing race conditions and memory leak console warnings.
2. System Testing
System tests validate the platform end-to-end by running both services as Docker containers against real (emulated) infrastructure via a pytest harness.
System Testing Flow
- Black-Box: Tests interact only through the same HTTP endpoints production clients use.
- Harness Verification: After dispatching an HTTP call, tests bypass APIs to assert directly on the infrastructure (e.g., verifying a DB insert or a Pub/Sub queue length).
- Eventual Consistency: We achieve deterministic test stability by utilizing active polling with deadlines rather than relying on arbitrary
sleep()delays. - Readiness Gates: Services utilize HTTP
/healthzgates to guarantee ordering (e.g., ML won't process until Core completes DB migrations).
Running System Tests
This transparently executes pytest tests/system/ and runs Pytest under the hood.
Anatomy of a System Test Flow
System tests use shared session fixtures to prevent massive teardown latency.
Seeding State
If a test requires an authenticated user, don't perform the HTTP login flow every time. Inject immediately into Postgres using a session-scoped fixture.
Mocking External Dependencies
External internet services (e.g., AssemblyAI) are replaced by a local mock HTTP server that supports WSS TLS. The tests assert against the mock server to guarantee wordloop services called the external API correctly.