Wordloop Platform
Platform Engineering

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

Rendering architecture map...
  1. Unit (70%): Pure domain functions. Zero infrastructure dependencies. Executed in milliseconds.
  2. Integration (20%): Provider layer. Real Postgres, GCS, and PubSub containers via testcontainers.
  3. 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 (mockery for 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

  1. Black-Box: Tests interact only through the same HTTP endpoints production clients use.
  2. 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).
  3. Eventual Consistency: We achieve deterministic test stability by utilizing active polling with deadlines rather than relying on arbitrary sleep() delays.
  4. Readiness Gates: Services utilize HTTP /healthz gates to guarantee ordering (e.g., ML won't process until Core completes DB migrations).

Running System Tests

./dev test system

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.

Rendering architecture map...

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.

@pytest.fixture(scope="session")
def test_user_id(postgres):
    conn = psycopg2.connect(postgres["connection_url"])
    conn.execute("INSERT INTO users (id, email) VALUES (%s, %s)", (gen_id(), "test@wordloop.test"))

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.

On this page