Testing Strategy - amalps565/Smart-Workspace-Seating-Chart GitHub Wiki
Testing Strategy
Commands are in
backend/CLAUDE.md,frontend/CLAUDE.md, and thee2e/section of the rootCLAUDE.md.
Test levels
| Level | Tool | What it covers |
|---|---|---|
| Backend unit | JUnit 5 | The neighbour policy in both modes: edges, corners, non-desk cells |
| Backend integration | JUnit 5 + Testcontainers PostgreSQL | Booking and cancel rules, every error code, constraints, authorization |
| Backend concurrency | JUnit 5 + Testcontainers | The race fix (recipe below) |
| Frontend unit | Vitest + Testing Library + MSW | Store rules, cell rendering, optimistic booking and rollback |
| End to end | Playwright, in the top-level e2e/ package |
Critical flows across the real backend, frontend, and database |
Integration and concurrency tests never use H2. Its locking behaves differently from PostgreSQL's.
Concurrency test recipe
The race fix isn't done until this passes repeatedly against real PostgreSQL.
- Seed a floor, a set of users, and a target date.
- Create N threads (for example 20), each with its own user.
- Hold every thread at a
CountDownLatchstart gate, then release them together. - Scenario A, same desk: every thread books the same desk.
- Scenario B, neighbouring desks: threads book a desk and its neighbours.
- Assert:
- Scenario A: exactly one booking exists, and every other request got
409 DESK_TAKEN. - Scenario B: no two booked desks on the floor and date are neighbours. Every rejected request got a 409, and there were no 500s or deadlocks.
- Scenario A: exactly one booking exists, and every other request got
- Repeat each scenario many times (for example 50) with
@RepeatedTest. One pass proves little.
Scenario B is the real write-skew race. Scenario A alone would pass with just a unique constraint.
Backend integration cases
- Every error code in Domain Rules, each with its HTTP status and body.
- Both neighbour modes, and a desk surrounded only by walkways.
- Cancelling someone else's booking → 403. Unauthenticated requests → 401.
- The WebSocket publishes after commit, and a rolled-back booking publishes nothing.
Frontend cases
- Socket updates arriving out of order or twice: the older
seqis ignored. - After a reconnect, the snapshot reloads and the map is correct.
- An optimistic booking that gets a 409 rolls back and shows the reason.
- A single desk update re-renders only the affected cells.
- Keyboard navigation and
aria-liveannouncements.
End-to-end cases
- Two browser contexts race for neighbouring desks. One wins, and the other sees the conflict message and the updated map.
- Booking in one browser appears in the other within moments.
- Cancelling frees the desk in both browsers.
Test quality rules
- Tests are deterministic: no
sleepwaits, no real clock or network dependence, and data is seeded explicitly. - A test for a bug fails before the fix and passes after it.
- Flaky tests get their cause fixed. Don't add retries or skip them.