Mobile permissions testing: camera, location, photos, notifications
Permission bugs are mobile-specific and easy to miss, because the happy path — grant on the first prompt — is the one state that always works. The bugs live in deny, revoke, and 'ask every time'.
part ofMobile QAMobile permissions are a testing surface with no web equivalent, and most teams test exactly one path through it: the app asks for the camera, you tap "Allow", the camera works. That state is real but it's the least interesting one. Real users deny prompts, grant them once and revoke them later, and change settings while the app is backgrounded — and that's where apps crash, hang, or silently do nothing. This is a concrete instance of why mobile bugs escape web-first teams.
The states that exist for every permission
For each permission your app uses — camera, location, photos/media, microphone, contacts, notifications — there isn't one state, there are several, and you need to test the app's behaviour in each:
- Not yet asked — the first-run state.
- Granted — the happy path.
- Denied once — the user tapped "Don't allow" on the prompt.
- Permanently denied — denied such that the OS won't show the prompt again; the app must deep-link the user to Settings.
- Granted then revoked — the user allowed it, used the app, then turned it off in system Settings later. The app comes back to a permission it used to have and no longer does.
- Limited / partial (iOS especially) — "select photos" instead of full library access, or "while using the app" instead of "always" for location.
The high-value test is almost never "granted." It's revoked-while-backgrounded: grant the permission, use the feature, background the app, turn the permission off in Settings, return to the app. A well-built app notices and handles it; a fragile one crashes or acts as if it still has access.
What goes wrong
The failure modes are consistent across apps:
- The denied path is a dead end. The feature just silently doesn't work, with no explanation and no route to fix it. The right behaviour is a clear message plus a button that deep-links to the OS settings page.
- The app crashes on revoke. Code assumes a permission it had at launch is still there. On resume it accesses the camera/location and throws.
- The prompt fires at the wrong time. Asking for location on first launch, before the user knows why, tanks the grant rate. Permissions should be requested in context, when the feature is used.
- Notification permission is forgotten entirely. It's a permission like any other — deny it, and push notification testing has a whole branch most teams skip.
- iOS and Android differ. Permission models, prompt timing, "limited" options, and the revoke experience aren't the same on both platforms — a pass on one is not a pass on the other.
Mobile permissions test pass (per permission)
- First run: prompt appears in context, with a rationale, not at cold launch
- Grant: feature works end to end
- Deny once: clear in-app explanation, no crash, no dead end
- Permanently denied: app detects it and offers a deep link to system Settings
- Granted then revoked in Settings (app backgrounded): app handles it gracefully on resume
- Limited/partial access (iOS photos, "while using" location): feature degrades sensibly
- Notifications: test the denied branch, not just granted
- Re-grant: turning the permission back on restores the feature without a restart (or with a clear prompt to)
- Run the whole matrix on both iOS and Android
Make it a matrix, not a checkbox
The reason permission bugs slip through is that teams treat "permissions" as one test case instead of a small matrix: permissions × states × platforms. It's not as large as it sounds — a handful of permissions, the states above, two platforms — and it catches a class of crash-and-dead-end bugs that real users hit constantly because real users say no, change their minds, and tinker with Settings. The office-Wi-Fi equivalent here is the always-granted tester; the bug you don't test is the state your users live in.
// RELATED QA.CODES RESOURCES
// related
My mobile smoke test before every release
A short, device-real smoke pass: permissions, offline, rotation, interruptions, and the update path.
Push notification testing: what usually goes wrong
Notifications behave differently foregrounded, backgrounded, and killed — and deep-link to the wrong place when they arrive. The killed-app cold start is where it breaks.