← Back to Projects
QA Testing

Bunker App — Bug Test Plan

24 bug test cases across crashes, gameplay logic, localization, UI, multiplayer sync, and security found during development of the Bunker Android game.

QABug TestingAndroidMobile

Bunker App — Bug Test Plan

All test cases sourced from this development session. Each entry maps to a real bug that was either reported by the user, discovered during implementation, or found in the code review.

Status legend: 🟢 Fixed & Verified | 🟡 Fixed, not re-tested live | 🔴 Known, not fixed


1. Crashes & Stability

#Test CaseSteps to ReproduceExpectedActual (Bug)Root CauseStatus
C-01Grid/table icon crashStart a game → tap the grid icon (📊) in the top bar on any phasePlayer cards table opensApp hard-crashes with IllegalStateException: infinity height constraintsLazyColumn nested inside Column(Modifier.verticalScroll()) — two competing scroll containers🟢 Fixed
C-02Game loading screen crashHost starts game from lobby (6+ players)Loading spinner, then game startsApp crashes instantly on loading screenNullPointerException or uninitialized state in GameViewModel on first Firebase snapshot🟢 Fixed

2. Gameplay Logic

#Test CaseSteps to ReproduceExpectedActual (Bug)Root CauseStatus
G-01[P0] Infinite tie revote loopGet a tie vote (two players with equal votes) → observe what happensGame goes to re-debate → re-vote once → if still tied, no elimination → continueGame loops ACCUSATION → DEFENSE → VOTING → ACCUSATION foreverrevoteCount never incremented when transitioning to ACCUSATION; old votes only cleared when revoteCount > 0, so same tied votes auto-re-trigger the tie path🟢 Fixed
G-02[P1] Reveal phase becomes no-op after round 1Play to round 2 → wait for your reveal turnRound 2 shows buttons to reveal 1–2 attributes”Done” state shown immediately, no reveal buttons appearhasRevealedEnough compared revealedAttributes.size (cumulative) against roundSlots[currentRound] (per-round delta, e.g. 2). After revealing 3 in round 1, size=3 ≥ 2, so always “done”🟢 Fixed
G-03[P1] Non-host player can advance phaseJoin as non-host player → reach your PLAYER_TURN reveal → tap “Done”Only host should advance phase/timerCurrent player (non-host) writes currentPhase, timerEndEpochMs, currentTurnPlayerUid to FirebaseonDoneTurn() only checks isMyTurn, not isHost; calls advancePhase() directly🟡 Known by design, not changed
G-04Start Game button non-functionalHost creates lobby → 6 players join → host taps Start GameGame starts for all playersButton tap does nothing on physical deviceFirebase write from Start Game failed silently; likely auth token or permission issue🟢 Fixed
G-05Special abilities not executingPlayer uses an ability during Discussion or Reveal phaseAbility effect applies (e.g. swap an attribute, reveal another’s card)Nothing happens — game state unchangedAbility system required host-manual handling; automatic execution was not implemented🟢 Fixed (redesigned as host-panel manual flow)

3. Localization & Language

#Test CaseSteps to ReproduceExpectedActual (Bug)Root CauseStatus
L-01Mixed language display (CRITICAL)Host device is in Russian → guest device is in English → start game → guest opens catastrophe reveal screenGuest sees English text throughoutGuest sees Russian catastrophe name, Russian bunker description, Russian amenities — mixed with English labelsHost wrote locale-specific text strings to Firebase. Guests read host’s language text because there was no index system yet🟢 Fixed (index-based localization)
L-02Russian gender agreement wrongPlay with a female character in Russian locale → open character sheet”Молодая”, “Атлетическая” (feminine forms)“Молодой”, “Атлетический” (masculine forms used for all)Enum stringResId had only one form; no feminine stringResIdF variant existed🟢 Fixed
L-03Untranslated lobby & in-game UISwitch device to Russian → go through lobby creation, join, and in-game screensAll UI text in RussianMix: some screens Russian, others still English (“Creating game…”, “Enter code”, phase names, accusation/defense/voting screens, “Paused”, “Body type”, “KG”)Hardcoded English strings in Compose composables instead of stringResource() calls🟢 Fixed
L-04”Paused” text hardcoded EnglishActivate any ability as host (causes game pause overlay) → observe on Russian device”Пауза""Paused”PendingAbilityOverlay.kt used a hardcoded English string🟢 Fixed
L-05Hebrew files contained Russian textSwitch to Hebrew locale → view character sheet or catastrophe screenHebrew textRussian text displayedHebrew JSON files were written with Russian content from a prior copy-paste error🟢 Fixed

4. UI Display

#Test CaseSteps to ReproduceExpectedActual (Bug)Root CauseStatus
D-01Bunker condition emoji always redStart a game where the bunker condition is “Excellent” or “Good” → view catastrophe revealGreen ✅ iconRed 🔴 icon regardless of actual conditionDisplay code matched condition by comparing English string prefixes. Russian locale strings never matched → fell to else → BunkerRed🟢 Fixed (use conditionIndex, not text)
D-02Survival time display brokenView catastrophe reveal on any device → read survival time row”You need to survive in the bunker for 2 years” formatted correctlyText appeared garbled / spacing wrong (e.g. “2years” or trailing space eaten)Android strips trailing spaces from strings.xml resources; space was part of the string resource🟢 Fixed (buildAnnotatedString with hardcoded spaces in Kotlin)
D-03Wrong survival time wordingView catastrophe reveal screen”You need to survive in the bunker for X""You have X to reach the bunker”Incorrect copy — implies travelling to bunker instead of surviving inside🟢 Fixed
D-04Attribute card display order wrongOpen character sheet → observe card orderSex → Age → Body type → Trait → Profession → Health → Hobby → Phobia → Inventory → Backpack → Extra infoDifferent order (e.g. Profession first, Sex last)Hardcoded column order in CharacterSheet.kt and PlayerCardsTable.kt not matching spec🟢 Fixed
D-05Health displayed without severityOpen character sheet → see health card”Brain cancer (Severe)""Brain cancer” with no severity shownSeverity was stored but not appended to the display string🟢 Fixed

5. Host Panel & Ability Overlay

#Test CaseSteps to ReproduceExpectedActual (Bug)Root CauseStatus
H-01”Open Host Panel” dismisses ability overlayPlayer uses ability → PendingAbilityOverlay appears → host taps “Open Host Panel”Panel opens but overlay stays; game remains pausedOverlay is dismissed when “Open Host Panel” is tapped — game resumes prematurely before host has handled the ability"Open Host Panel" button called onDismiss() which cleared pendingAbility in Firebase🟢 Fixed (only ”✓ Done, Resume” calls onDismiss)
H-02[P2] Host randomize breaks localizationHost opens host panel → randomizes a player’s profession, hobby, phobia, inventory, backpack, health, or extra info → Russian/Hebrew player views the cardPlayer sees new value in their own languagePlayer sees old value (old index still points to old profession) or sees host’s language textonRandomizeAttribute() wrote only text fields to Firebase, not the corresponding *Index fields. Display resolves by index first, so old index persisted🟢 Fixed

6. Multiplayer & Sync

#Test CaseSteps to ReproduceExpectedActual (Bug)Root CauseStatus
M-01”Join Game” button unresponsiveLaunch app → tap “Join Game” → enter a valid 6-char codeButton activates (turns green), tap proceeds to lobbyButton remains inactive, tap does nothingInput validation not wired to button enabled state; or onValueChange not triggering recomposition🟢 Fixed
M-02Phase transition delay on 3+ devicesHost + 2 guests on same Firebase → host advances phaseAll devices switch phase simultaneously (< 1s)Guests update several seconds late; only with 3 devices not 2Android Studio emulator network throttling; physical-only testing showed normal sync🟡 Not a bug (Android Studio issue)

7. Security

#Test CaseSteps to ReproduceExpectedActual (Bug)Root CauseStatus
S-01[P1] Firebase rules allow any auth user full write accessHave any Firebase-authenticated account → write to /games/{any-code}/currentPhase directly via REST or Firebase consoleWrite rejected (only host can change phase)Write succeeds — any signed-in account can modify any game’s phase, timer, players, or delete the gamedatabase.rules.json had .write: "auth != null" on all paths with no player/host checks🟢 Fixed
S-02[P1] Non-host player writes phase on their turnNon-host player is on PLAYER_TURN → taps “Done”Only host should write phase/timer to FirebaseNon-host player successfully writes currentPhase, timerEndEpochMs, currentTurnPlayerUidonDoneTurn() checks isMyTurn (not isHost) before calling advancePhase() which does a full Firebase phase write🟡 Architectural issue, not changed

8. Host Disconnect / Abandonment

#Test CaseSteps to ReproduceExpectedActual (Bug)Root CauseStatus
X-01Host checking another app ends the gameHost is in active game → host switches to messages app or home screen for 30–60 seconds → returnsGame continues normallyGame ends immediately for all players (ABANDONED phase triggered)onDisconnect() Firebase hook fires when Android pauses the app after ~60s background; any notification check could end the game🟢 Fixed (replaced with 10-minute heartbeat system)

Summary

CategoryTotalFixedNot Fixed / By Design
Crashes & Stability220
Gameplay Logic541 (non-host writes — by design)
Localization & Language550
UI Display550
Host Panel & Abilities220
Multiplayer & Sync211 (Android Studio issue)
Security211 (architectural)
Host Disconnect110
Total24213

Regression Checklist (Run Before Each Release)

These are the most likely areas to regress when adding new features:

  • Start a game with a Russian host + English guest — verify all text on guest is in English (index-based localization)
  • Play to a tie vote twice — verify the game reaches ROUND_RESULT with no elimination (not infinite loop)
  • Play to round 2 — verify reveal buttons appear (cumulative reveal counter)
  • Use an ability → tap “Open Host Panel” → verify game is still paused
  • Host randomizes a player’s profession → Russian guest checks the character sheet → verify new profession is in Russian
  • Switch to Russian → open lobby, join screen, accusation phase, defense phase, voting phase — verify all text translated
  • Host backgrounds the app for 30 seconds → verify game does NOT end
  • Host backgrounds the app for 11 minutes → verify guests see ABANDONED screen