Quick answer: Test push notifications across delivery state and app state. Confirm notifications arrive, render correctly, and route to the right screen whether the game is foregrounded, backgrounded, or closed. Then verify opt-out is honored everywhere, permissions are requested at a sensible moment, and tapping a notification never lands the player on a blank screen or a stale state.
Push notifications are one of the few times your game speaks to a player who is not currently playing, which makes a broken one disproportionately costly. A notification that fires after a player opted out feels like a betrayal, and a tap that opens a blank screen feels like the game is broken. Notifications are hard to QA because their behavior forks on app state, on permission state, and on which platform delivered them. This post lays out a concrete pass covering receiving and tapping notifications, foreground versus background handling, deep routing, and honoring opt-out so you ship something that respects the player.
The states a notification has to handle
Every push notification has to survive a grid of conditions, and bugs live in the cells you forget to check. The first axis is app state: foregrounded, backgrounded, or fully closed. The platform delivers and displays notifications differently in each, and your game's handler runs in a different context each time. A notification that shows a system banner when closed might need your code to render an in-game toast when foregrounded, because the operating system suppresses banners while your app is active.
The second axis is the action: does the notification merely arrive, or does the player tap it. Arrival without a tap should update any relevant in-game state, like a badge or an inbox, without yanking the player anywhere. A tap should route to the screen the notification is about. Test arrival and tap as separate cases, because a handler can route correctly on tap while quietly failing to update state on silent arrival, or vice versa.
Foreground versus background behavior
When your game is in the foreground, the operating system usually hands the notification to your code instead of showing a banner, and it is your responsibility to decide what the player sees. The common bug is doing nothing, so a player who is actively playing never learns that their energy refilled or their friend came online. Decide deliberately whether a foreground notification becomes an in-game toast, an inbox entry, a badge, or is simply suppressed, and then test that the chosen behavior actually fires.
In the background or closed state, the system shows the notification and your code runs only when the player taps. The risks here are routing and freshness. Routing must open the correct screen, and the data behind that screen must be current rather than a cached view from hours ago. Test by sending a notification, waiting, changing the underlying state on the server, then tapping, and confirm the player sees the live state, not a stale snapshot captured when the notification was first composed.
Tapping, routing, and cold launch
A tapped notification that launches a closed game is the push equivalent of a cold start deep link, and it shares the same hazard. The notification payload carries a destination, and that payload has to survive your splash, authentication, and initial load before your router can act on it. Force-quit the game, send a notification, tap it, and confirm the player lands on the exact intended screen rather than the default home view. Repeat for every notification type you send, because each one carries a different payload your router must understand.
Routing also has to fail gracefully. A notification about a limited-time event that has since ended should not crash or hang on a missing event. A notification about a friend request that was already accepted should resolve to a sensible screen with a clear note. Build a small table of every notification type and its intended destination, then verify each tap, including the cases where the referenced thing no longer exists by the time the player gets around to tapping.
Permissions and respecting opt-out
When and how you ask for notification permission shapes both your opt-in rate and your trust. Asking on the very first launch, before the player understands what notifications are for, usually earns a hard decline that is awkward to reverse. Test that your permission prompt appears at a moment that makes sense, that declining is handled without nagging, and that the game still functions fully with notifications off. A game that degrades or repeatedly re-prompts after a decline reads as disrespectful.
Opt-out must be honored everywhere, and this is the test most often skipped. After a player disables a notification category in your settings or at the system level, confirm that category genuinely stops arriving, including server-triggered sends that may not check the latest preference. Test the round trip: opt out, trigger the event that would normally notify, and verify silence. Then opt back in and verify delivery resumes. A notification that arrives after opt-out is not a minor bug, it is the kind of thing that gets your game uninstalled.
Setting it up with Bugnet
Notification bugs are notoriously underreported because the player is not in the game when they happen, and by the time they open it the evidence is gone. When a player does report a problem, Bugnet's in-game report button captures game state automatically, so you get the player's notification settings, permission status, current screen, platform, and build attached to the report. That context turns I got a notification after turning them off into something you can actually trace to a server send that ignored the latest preference.
If a tapped notification crashes on cold launch, Bugnet's crash reporting captures the stack trace and device context, showing whether the failure is in your payload parser, your router, or your session load. Occurrence grouping folds the many duplicate reports from a single misbehaving notification template into one issue with a count, so you can see which notification type is actually causing the noise. Custom fields let you tag reports by notification category and triage them from one dashboard.
A repeatable notification QA pass
Turn the grid into a checklist you run each release: each notification type, crossed with foreground, background, and closed, for both arrival and tap, plus the opt-out round trip. Keep a way to fire test notifications on demand, whether a debug menu or a small server tool, so QA is not waiting on real triggers that fire once a day. Pre-stage edge cases too, like a notification that points at an event you can expire on cue, so the stale and missing data paths are easy to exercise.
Coordinate with whoever owns the sending side, because half of notification correctness lives on the server. The client can route flawlessly and still deliver a broken experience if the server sends to opted-out players or composes payloads with stale data. Treat notifications as a shared contract between client and server, test both ends, and you will ship something that reaches players at the right moment with the right respect for their choices.
Notifications fork on app state and permission state. Test arrival and tap separately, honor opt-out everywhere, and never let a tap land on a blank screen.