🧪 EditMode Tests (294 tests, 21 files)
Run without starting the Unity game loop. Test pure logic, data structures, math, and configuration. Use [Test] attributes and mock dependencies. Instantiate components via new GameObject().AddComponent<T>() with manual wiring — no scene required. Fast, deterministic, no frame waits.
🎮 PlayMode Tests (76 tests, 11 files)
Run inside the Unity runtime with a full game loop. Use [UnityTest] coroutines that yield frames (yield return null) to test real component lifecycles, Start()/Awake() execution, physics, rendering, and time-based behavior. Used for integration tests and visual effects validation.
🤖 Automated Play Testing (M6)
A full headless game session runner (PlayTestRunner) boots 1–4 AI bot players (BotPacmanController with BFS pathfinding + ghost avoidance), runs configurable rounds, and outputs structured JSON results. PlayTestInvariantValidator checks 6 game invariants. Run-PlayTests.ps1 gates the deploy pipeline.
🔧 Test Framework & Tooling
All tests use NUnit 3.x via Unity Test Framework. Two assembly definitions: PacmanRoyale.Tests.EditMode and PacmanRoyale.Tests.PlayMode. Tests run in Unity batchmode (-runTests -testPlatform EditMode|PlayMode). Results output as NUnit XML. CI script parses XML and JSON for pass/fail gating.
| System | Test File | Type | Tests | What It Validates |
| Maze Generation | MazeLayoutTests.cs | EditMode | ~12 | Tile access, bounds, wall detection, passability queries |
| Classic Maze Data | ClassicMazeDataTests.cs | EditMode | ~14 | 28×31 grid integrity, dead-end regression guard, pellet/wall counts |
| Pellet System | PelletManagerTests.cs | EditMode | ~16 | Collection, repopulation, power pellet events, Reinitialise() |
| Ghost AI | GhostNavigationTests.cs | EditMode | ~15 | Direction choice, Blinky/Pinky/Inky/Clyde targeting, ghost-house blocking |
| Ghost State Machine | GhostStateMachineTests.cs | PlayMode | 14 | State transitions, frightened/dead speed, sprite hide/show, house exit bugs |
| Ghost Release Config | GhostReleaseConfigTests.cs | EditMode | 6 | Spawn tiles inside house, exit tile correctness, no spawn==exit |
| Player State | PlayerStateTests.cs | EditMode | ~8 | Score add, lives decrement, death tracking |
| Elimination Tracker | EliminationTrackerTests.cs | EditMode | ~14 | Registration, death recording, alive count, winner detection |
| Attack & Combo | AttackSystemTests.cs | EditMode | ~12 | Combo step escalation (200/400/800/1600), reset on power expire |
| Targeting System | TargetingSystemTests.cs | EditMode | ~18 | Mode cycling (KO/Attacker/Random/Manual), OnModeChanged events |
| Input Profiles | InputPlayerProfileTests.cs | EditMode | ~9 | Control scheme assignment, rotated input for P3/P4 |
| Local Multiplayer | LocalMultiPlayerLoopTests.cs | EditMode | 14 | BeginGame bitmask, game-over detection (1p/multi/draw), OnGameOver events, reset |
| Grid Movement | GridMoverTests.cs | PlayMode | ~10 | Tile-to-tile movement, input buffering, frozen state, tunnel wrap |
| Pac-Man Controller | PacmanControllerTests.cs | PlayMode | 4 | Die hides sprite, IsAlive false, respawn re-enables sprite, IsAlive true |
| Audio System | AudioManagerTests.cs (Edit) + PlayMode | Both | 20 | Init, BGM play/pause, SFX trigger, volume prefs persistence |
| Victory Fanfare | VictoryFanfareTests.cs | EditMode | 10 | Clip generation, sample rate, mono, duration, non-silent, idempotent |
| Visual Effects | VisualEffectsTests.cs | PlayMode | 7 | Death effect spawn/destroy, pellet effect normal/power, self-destruct timing |
| Visual Polish | VisualPolishTests.cs | PlayMode | 11 | Maze glow, border FX brackets, combo popup, flash effect, players-remaining HUD |
| Visual Features (S2) | VisualFeaturesTests.cs | EditMode | 30+ | Season-2 effects, bug fix regressions (HUD hide, spawn tiles, pellet reinit) |
| Power Pellet Effects | PowerPelletEffectsTests.cs | PlayMode | 7 | Timer HUD show/hide/color, PowerActivateEffect spawn/destroy/ring children |
| HUD & Screen Shake | HudAndShakeTests.cs | PlayMode | 4 | Targeting label update, ScreenShake activation |
| Polish Systems | PolishSystemTests.cs | PlayMode | 1 | PelletPulse sine wave modulation |
| Online Lobby | OnlineLobbyDefaultsTests.cs + OnlineLobbyScreenTests.cs | Both | 15 | Default server/room values, scheme stripping, Awake prefill behavior |
| Online Multiplayer | OnlineMultiplayerTests.cs + OnlineNameTests.cs | EditMode | 25+ | Frozen state, NetworkControlled, spawn tiles, ForceRemoveTile, visual states |
| Network Session | NetworkSessionStubTests.cs | EditMode | ~7 | INetworkSession stub contract, options, session lifecycle |
| M7 Neon UI | M7VisualTests.cs | EditMode | 38 | NeonAmbientBg, NeonScreenTransition, HighResSprites, ArcadeHudChrome, AttractMode, CabinetBorder, EnhancedParticles, PowerUpSprites |
| Bot AI | BotPacmanControllerTests.cs | EditMode | 14 | BFS pathfinding, ghost avoidance, aggression levels, null safety |
| Play Test Invariants | PlayTestInvariantTests.cs | EditMode | 18 | Validator logic: no exceptions, scores valid, lives valid, game-over reached |
| Play Test Runner | PlayTestRunnerTests.cs | PlayMode | 7 | Scene build, maze integrity, bot instantiation, session completion |
The test suite is comprehensive for game logic but has known gaps in the following areas:
🌐 End-to-End Online Networking
No tests exercise a full FishNet server + WebSocket client connection. Online tests validate data structures, state flags, and broadcast payloads in isolation — but not actual packet send/receive over a real transport. Verifying online play requires manual testing with the deployed server.
🖥️ WebGL-Specific Behavior
Tests run in the Unity Editor (Windows). WebGL-specific issues (IL2CPP stripping, browser JS interop via pacman-webgl.jslib, Brotli decompression, mixed-content HTTPS restrictions) are not exercised by the test suite and require manual browser testing.
📐 Visual Pixel-Accuracy
Tests confirm that visual-effect GameObjects are created and self-destruct on schedule, but do not perform screenshot comparison or pixel-level rendering validation. Visual regressions (glitched sprites, wrong colors, z-fighting) require human review or a future screenshot-diff pipeline.
⏱️ Timing-Sensitive Edge Cases
Two tests are inconclusive due to frame-timing sensitivity: DeathEffect_SelfDestructs_AfterDuration (PlayMode) and ChooseDirection_BlocksGhostHouseWhenFlagFalse (EditMode). These pass intermittently but depend on exact frame timing that varies by machine load.
📱 Mobile / Touch Input
No tests cover mobile swipe controls or touch input. US-20 (mobile swipe controls) is in the backlog but not started. All input tests assume keyboard schemes (WASD, Arrows, IJKL, Numpad).
🔊 Audio Output Verification
Audio tests validate that AudioManager creates clips, sets volumes, and persists preferences. They do not verify that sound actually plays through speakers. Procedural audio waveform correctness is tested (non-silent, valid AudioClip) but not perceptual quality.