Testing¶
Prescriptive testing policy for SectorWars 2102. This document describes how testing should work across the source repos. Coverage gaps for specific features are tracked inline in FEATURES/ using the 🚧 Partial or 🐛 Bug markers — not here.
Test landscape¶
Tests live alongside the code they cover, in the source repos:
| Surface | Location |
|---|---|
| Gameserver (Python) | Sectorwars2102/services/gameserver/tests/ |
| Admin UI (TypeScript / React) | Sectorwars2102/services/admin-ui/ (colocated with components) |
| Player client (TypeScript / React) | Sectorwars2102/services/player-client/ (colocated with components) |
| End-to-end | Sectorwars2102/e2e_tests/ |
| World / sector generator | sw2102-bang/ (colocated; mirror gameserver conventions) |
sw2102-docs itself does not host tests; documentation lints (link-checking, formatting) belong in this repo's CI as defined under "CI" below.
How to run tests¶
Gameserver¶
From Sectorwars2102/services/gameserver/:
- Full suite:
pytest - One file:
pytest tests/test_<module>.py - One test:
pytest tests/test_<module>.py::test_<name> - With coverage:
pytest --cov=src --cov-report=term-missing
Admin UI¶
From Sectorwars2102/services/admin-ui/:
- Full suite:
npm test - Watch mode:
npm test -- --watch - One file:
npm test -- <path-or-pattern>
Player client¶
From Sectorwars2102/services/player-client/:
- Full suite:
npm test - Watch mode:
npm test -- --watch - One file:
npm test -- <path-or-pattern>
End-to-end¶
From Sectorwars2102/e2e_tests/:
- Full suite:
npx playwright test - One spec:
npx playwright test foundation-sprint/<spec>.spec.ts - Headed (debugging):
npx playwright test --headed - UI mode:
npx playwright test --ui
E2E tests assume the full local stack (gameserver, admin-ui, player-client, database, redis) is running. See ARCHITECTURE/ for the dev-environment bring-up.
What we test at each layer¶
The target test pyramid:
Unit tests¶
- Where: colocated with the code they cover, in each service.
- What: pure functions, service classes with mocked dependencies, individual React components, schema validators.
- Speed target: the full unit suite for any one service runs in under a minute.
- Required for: every public function in a service module; every component with conditional rendering or input handling; every model validator.
Integration tests¶
- Where:
services/gameserver/tests/integration/for backend,e2e_tests/for cross-service. - What: API endpoint behaviour against a real database; WebSocket flows against a real Redis; cross-service contracts (e.g. gameserver ↔ admin-ui auth).
- Required for: every REST and WebSocket endpoint exposed by the gameserver; every multi-step workflow that touches more than one service.
End-to-end tests¶
- Where:
Sectorwars2102/e2e_tests/. - What: player-visible flows running through the player client and admin UI against the real stack. Examples: first login flow, trade-loop happy path, combat resolution, multi-channel chat, sector transition.
- Required for: every flow described in a
FEATURES/doc as user-facing.
A feature is not considered ✅ Shipped in FEATURES/ until it has at least one e2e test or documented manual test plan covering its happy path.
How to add a new test¶
Gameserver¶
- Add a file under
Sectorwars2102/services/gameserver/tests/namedtest_<module>.pymatching the module under test. - Use
pyteststyle (functions, not classes) unless the test needs shared setup. - Use the existing fixtures in
tests/conftest.pyfor database and authentication. - For DB-backed tests, mark with
@pytest.mark.integrationif the test requires a live database; leave unmarked for pure unit tests. - Run
pytest tests/test_<module>.pylocally before committing.
Admin UI / Player client¶
- Add a
<Component>.test.tsxfile next to<Component>.tsx. - Use the project's existing test renderer wrapper (provides router, query client, theme).
- Prefer testing user-visible behaviour (queries by role, label, text) over implementation details.
- Mock network calls at the fetch boundary, not at the component boundary.
- Run
npm test -- <ComponentName>locally before committing.
End-to-end¶
- Add a
.spec.tsunder the appropriate subdirectory ofe2e_tests/(e.g.foundation-sprint/,multi-regional/). - Use the existing page-object helpers; do not select by raw CSS unless no role/label exists.
- Each spec should be independently runnable — set up its own seed data, clean up after itself.
- Run
npx playwright test <spec>locally with the full stack up before committing.
CI¶
Continuous integration runs on every PR and on every merge to the main branch. The target pipeline lives at .github/workflows/ in the source repos.
Per-PR jobs:
- Lint — language-appropriate linters for each service.
- Unit tests — full unit suite for each service, run in parallel.
- Integration tests — gameserver integration suite against a CI-provisioned Postgres and Redis.
- E2E tests — Playwright suite against a CI-provisioned full stack.
- Doc checks — for
sw2102-docs, link validation and conventions checks perCONTRIBUTING.md.
Per-merge jobs additionally:
- Build container images for each service.
- Run smoke tests against the resulting images.
A PR is not mergeable until every required check passes. Flaky tests are not retried at the CI level — fix them or quarantine them with an explicit 🐛 Bug entry in the relevant FEATURES/ doc.
Coverage and quality¶
Target coverage is meaningful coverage, not a percentage. Each test should:
- Have a clear name describing the behaviour under test.
- Fail for one specific reason.
- Either run fast (unit) or test something a fast test cannot (integration, e2e).
When a feature is added, the corresponding FEATURES/ doc and at least one test are part of the same PR. If you find a coverage gap on an existing feature, mark the feature 🚧 Partial and link to the gap in the feature doc — do not silently add a TODO here.