# Scrabble Game — Testing How the project is tested and the gate every stage must pass. Read before adding tests or touching CI. ## Layers - **Go unit tests** — table-driven where it helps; `testing` + standard library. Every functional change ships with regression coverage. Run: `go test -count=1 ./backend/...` (the module list grows with the workspace). - **Integration** *(introduced with Postgres in Stage 1)* — `testcontainers-go` spins real dependencies (Postgres). Slow; a separate CI workflow. - **UI** *(introduced with the UI in Stage 7)* — Vitest (unit) + Playwright (e2e), mirroring the chosen plain-Svelte + Vite toolchain. - **Engine** — correctness of scoring and move generation is owned by `scrabble-solver`'s own GCG-backed tests. The backend adds regression tests for end-conditions, the 24-hour timeout / auto-resign, robot balance and margin targeting, and **dictionary-independent history replay**. ## Principles - A green run must not depend on cached state: use `-count=1` in CI. - Tests that need infrastructure fail loudly (`t.Fatal`) when it is unavailable rather than silently skipping coverage. - No network or real platform calls in unit tests; validate platform credentials behind an interface seam and test with fixtures. ## Per-stage CI gate Every completed stage is exercised on `gitea.iliadenisov.ru` before it is marked done in [`../PLAN.md`](../PLAN.md): 1. Commit the stage on its `feature/*` branch. 2. Push to `origin`. 3. Watch the run to completion — never hand-roll a poll loop: `python3 ~/.claude/bin/gitea-ci-watch.py` (launch in the background). 4. Only after every workflow that fired is green may the stage be marked done.