Testing Strategy
Relevant source files
The following files were used as context for generating this wiki page:
The Dreamcats project employs a multi-layered testing strategy designed to verify frontend state management, backend game invariants, and end-to-end gameplay flows. The strategy relies on Vitest for unit and integration testing, and a specialized Convex testing environment to simulate real-time database mutations and queries in-memory.
This approach ensures that core gameplay mechanics—such as deck integrity, turn logic, and scoring—remain deterministic and free from network-related flakiness. High-level testing is further supported by an AI test agent that exercises complex action sequences and special card powers without requiring a deployed backend.
Sources: convex/TESTING.md:1-8, scripts/ai-agent.ts:1-12, AGENTS.md:10-15
Backend & Integration Testing
The backend testing infrastructure utilizes convex-test to run Convex functions in-memory. This allows for the verification of game invariants such as deck size, unique seat assignments, and idempotent writes without hitting a live environment.
Core Testing Objectives
- Room Management: Verifying unique seat assignments and host initialization.
- Game State Invariants: Ensuring deck composition (54 cards) and proper card distribution (4 per player) at round start.
- Idempotency: Testing that
setGameStateand other mutations reject stale versions and handle retries gracefully.
Sources: convex/TESTING.md:11-19, convex/tests/rooms-and-games.test.ts:133-145
Convex Test Flow
The following diagram illustrates how Convex functions are loaded and executed within the test environment.
The testing environment mirrors the production API, allowing developers to exercise mutations exactly as the client would.
Sources: convex/TESTING.md:22-25, convex/tests/rooms-and-games.test.ts:10-11
Frontend State & Logic Testing
The frontend testing focus is divided between raw game logic utilities and the Zustand-based application stores.
Game Logic Utilities
Unit tests verify the deterministic nature of the deck creation and shuffling logic.
| Component | Test Focus | Expected Result |
|---|---|---|
createDeck | Composition | 54 cards: 36 (0-8), 9 (9s), 9 (Specials) |
shuffleDeck | Integrity | Same length, same IDs, non-mutating |
| Special Cards | Values | take_2=5, peek_1=6, swap_2=7 |
Sources: src/tests/game-logic.test.ts:4-60
State Management (Zustand)
Tests for useAppStore and useTutorialStore ensure that state slices (Session, Game, UI, Net) update correctly and that subscriptions trigger as expected.
- Reactivity: Using
useAppStore.subscribeto verify that nested game state changes (e.g.,gamePhase) trigger updates. - Selectors: Testing auto-generated selectors (e.g.,
useAppStore.use.playerId()) for accuracy. - Persistence Mocking: Browser APIs like
localStorageare mocked to support Zustand's persistence middleware.
Sources: src/tests/store.test.ts:11-25, src/tests/selectors.test.ts:88-115, src/tests/setup.ts:8-25
End-to-End Gameplay Simulation
The ai-agent.ts script acts as a headless client to exercise end-to-end flows. It simulates multiple players across multiple rounds to ensure all game phases are reachable.
AI Agent Execution Flow
The agent can be configured for different modes, including "advanced" mode which primes the deck to ensure special card paths (Swap 2, Take 2, Peek 1) are exercised.
Testing Commands
| Command | Action |
|---|---|
bun run test | Runs Vitest in watch mode |
bun run test:run | Executes tests once (CI mode) |
bun scripts/ai-agent.ts | Runs the AI test agent simulation |
Sources: package.json:7-12, AGENTS.md:7-8
Conclusion
The testing strategy combines granular unit tests for pure logic with robust integration tests for state and network flows. By utilizing an in-memory Convex instance and an automated AI agent, the project maintains high confidence in gameplay integrity and state synchronization across complex multiplayer scenarios.