Mobile permission testing verifies how an app requests, receives, and handles OS-level runtime permissions: camera, location, notifications, contacts, biometric, microphone, photos, calendar, and health data. Every one of these has a runtime prompt, a set of possible user responses, and an app-side flow that either handles the response correctly or crashes on the way to the next screen.
Most functional test suites cover happy path where user grants every permission. That's state where app behaves like it did in dev. The bugs live everywhere else on denial, "never ask again," mid-session revoke, and OS-version-specific prompt copy.
The rest of this piece defines mobile permission testing from a QA lead's operational view, not a security-audit view, and maps the permission state machine to tests that catch what actually breaks.
What is mobile permission testing?
Mobile permission testing is a category of testing that verifies an app's behaviour across full permission lifecycle: pre-prompt state, prompt itself, every possible user response, and every subsequent state transition.
Security-focused permission testing with the OWASPOWASP MASTG angle checks whether an app requests permissions it doesn't need. That's a static audit of Info.plist and AndroidManifest.xml, not a runtime test.
QA permission testing verifies runtime behaviour: does the app handle a denial without crashing, does it show a useful fallback, does it recover when user grants permission later?
Both matter. This piece is about the runtime behaviour side.
On Drizz, runtime prompts that app under test can't dismiss on its own are auto-handled by blocker rules at org-level same mechanism that dismisses promo sheets and network retries. The test targets app's response to result, not mechanics of tapping OS dialog.
Which mobile permissions need explicit tests?
Nine permission categories cover most of what mobile apps request. Each has its own dialog, its own state persistence, and its own failure modes.
- Camera: Photo capture, QR scanning, video calls. iOS-only distinction between full and limited photo access on iOS 14+.
- Location: GPS, background location, precise vs approximate on iOS 14+ and Android 12+.
- Notifications. Push, local, provisional (iOS), and notification categories.
- Contacts. Read, write, or have limited contact access on iOS 18+.
- Biometric. Face ID, Touch ID, fingerprint. Handled by Apple's Local Authentication framework or Android's BiometricPrompt.
- Microphone. Voice notes, video calls, transcription.
- Photos and media. Full library access vs limited/selection-only access.
- Calendar and reminders. Event creation, invitations.
- Health data. HealthKit on iOS, Health Connect on Android. Consent per data type.
For each, the test scope has to cover the copy shown in prompt, app's behavior on each response, state after backgrounding, and recovery path when user changes their mind in settings.

How do permission states change across the mobile permission lifecycle?
Every permission moves through a state machine that has more than "granted" and "denied." Missing states are where silent bugs live.
- Not asked. The app hasn't prompted yet. Some flows shouldn't; others must before they can proceed.
- Prompted. The OS dialogue is on screen. The app is paused. State-restoration bugs surface here if app is killed mid-prompt.
- Granted (full). User tapped Allow, no scoping. Standard happy path.
- Granted (limited or approximate). iOS 14+ location precision toggle; iOS 14+ Photos "Selected Photos"; iOS 17 location precision downgrade at runtime. Test that app degrades gracefully to reduced scope.
- Denied. User tapped Don't Allow. App should render a fallback rather than a broken screen.
- Denied (never ask again). Android's USER_FIXED state or iOS's absence of a re-prompt option. App must direct user to Settings.
- Revoked from Settings. User granted before, then revoked mid-session or between sessions. The state change surfaces on next feature use.
- Downgraded from Settings. Precise location changed to approximate. Photos changed from full to limited. Same test surface as revoke.
Any test suite that only covers "granted" and "denied" is testing two of eight states. The other six ship as production bugs.
How does mobile permission behavior differ across iOS and Android versions?
OS versions change permission behavior in ways that break tests written for previous version. A short list of OS-version cliff-edges that matter now.
- Android 6 (API 23). Runtime permissions introduced. Anything below is manifest-only.
- Android 11 (API 30). One-time grant. The user can pick "Only this time," and permission auto-revokes when app is backgrounded.
- Android 12 (API 31). Approximate location. User can downgrade a precise-location request to approximate at prompt.
- Android 13 (API 33). Notifications became a runtime permission. Older apps that assumed notifications-by-default now need an explicit prompt.
- Android 14–15. Selective photo/media access; partial background location scopes.
- iOS 13. Location "Allow Once" and "Allow While Using App" options.
- iOS 14. App Tracking Transparency added. Approximate location and limited-photos options landed.
- iOS 17. Users can revoke precise location without revoking approximate.
- iOS 18. Contact-access granularity apps can be granted a subset of contacts rather than all-or-nothing.
Tests written before any of these changes need to be re-verified on each new OS version. Otherwise same test that passed on iOS 15 quietly asserts on a UI element that no longer exists in iOS 17.
Which mobile permission bugs are hardest to catch?
The blocking permission bugs cluster in six patterns. Automated tests catch three of them consistently; other three usually need a manual pass.
- Missing rationale before prompt. iOS and Android both require (or strongly recommend) an in-app explanation before OS prompt fires. Apps that skip this see denial rates 30–50% higher than apps that show one.
- Crash on denial. The most common blocking bug. The feature calls a permission-guarded API without checking state; on denial, app crashes trying to use nil or null.
- No fallback UI on denial. No crash, but no recovery either. A camera-required screen renders blank because app assumed permission would be granted.
- "Never ask again" with no path to Settings. The user has to know to enable it manually, without any in-app link. On Android this is a shipping bug; on iOS it's a UX bug that reads as a shipping bug.
- Silent state after revoke. The user granted permission, used feature, revoked in Settings, and came back. The app still shows feature as available and errors when they try to use it.
- State restoration mid-prompt. The app killed itself (memory pressure) while OS prompt was up. On restart, flow doesn't resume from prompt it resumes from state before, and user has to repeat setup.
Testing for these needs ability to script OS dialog response, which is where tool choice matters.

How do you write a mobile permission test case?
A permission test case extends standard four-part structure with two extras: permission preconditions and response.
- Permission preconditions. The current state for every permission flow touches. Not just one being tested app's response also depends on which other permissions have already been granted or denied.
- Steps. The user actions up to and past prompt, including which button user taps on OS dialog.
- Expected result. Both immediate app response (UI update, banner) and state written to OS permission store.
- Cleanup. Reset permission state so subsequent tests start from a known baseline.
On tooling side, Appium's GrantPermissionRule pre-grants permissions so test never sees dialog. That works when you're testing granted path, but it hides every bug in denial and revocation paths.
The vision-based approach targets actual system dialog: Validate that dialog appears with expected copy, Tap target button ("Allow" or "Don't Allow"), then assert on app's response. The authoring rules require targeting visible label on dialog, which surfaces copy regressions between OS versions as authoring-time signals.
For scenarios where app has to reach settings to recover the never-ask-again path system commands drive OS settings app rather than AUT.
When should mobile permission tests run in release pipeline?
Permission tests belong at three pipeline positions.
- Per-PR CI. Two or three smoke tests covering happy path plus one denial path. Runs on head-tier device fleet. Gates merge on app not crashing when a permission is denied.
- Nightly. Full permission state matrix across every permission app requests. Includes background transitions and Settings-app revoke paths.
- Release candidate. Full permission suite plus OS-version-specific tests for any versions supported by release. Human review on any updated prompt copy.
Any change to a permission-requesting feature, any bump of target SDK on Android or deployment target on iOS, and any change to Info.plist or AndroidManifest.xml triggers an out-of-band permission sweep. Those changes are most common source of silent regressions.
For broader placement in a mobile testing strategy, see device tier and release stage matrix permissions typically run on same head-tier devices as functional tests, but with permission state explicitly set in preconditions rather than left as whatever last test left behind.
Conclusion
Mobile permission testing verifies app behavior across runtime permission lifecycle for camera, location, notifications, contacts, biometric, microphone, photos, calendar, and health data. Each permission moves through eight states, not two and six of those states are where silent bugs ship.
OS-version differences reshape test surface every year. Android 11's one-time grant, Android 13's notification runtime prompt, iOS 14's App Tracking Transparency, iOS 17's location revoke, iOS 18's contact granularity each changed a test that was passing.
A permission test case adds permission preconditions and OS-dialogue response to the standard four-part structure. Testing denial and revocation paths matters more than testing happy path, because happy path is what dev already covered.
Pipeline placement runs a small smoke set per PR, full state matrix nightly, and OS-version-specific tests at release candidate. Manifest and SDK-target changes trigger out-of-band sweeps.

FAQs
What's the difference between mobile permission testing and mobile security testing?
Mobile security testing (OWASP MASTG framing) audits whether an app declares permissions it doesn't need a static check on Info.plist or AndroidManifest.xml. Mobile permission testing verifies runtime behavior what app does when user grants, denies, or revokes. Security asks whether permission should be requested; permission testing asks whether response is handled.
Which permission states should a mobile team test beyond granted and denied?
Six additional states matter: not-asked (before prompt), prompted (mid-dialog with app paused), granted-limited (iOS 14 Photos, iOS 14 precise-vs-approximate location, iOS 18 partial contacts), denied-never-ask-again (Android USER_FIXED), revoked-from-settings, and downgraded-from-settings (precise to approximate). Skipping these leaves six-eighths of state machine untested.
How do you test permission denial on Android and iOS?
On Android, use adb shell pm revoke <package> <permission> to force a denied state, then run flow that would prompt and verify app renders a fallback rather than crashing. On iOS, revoke through Settings before test starts, or use a UI test that taps "Don't Allow" on actual dialog. Vision-based runners target dialog by visible label rather than pre-granting.
What are most common mobile permission bugs that reach production?
Crash on denial (feature calls a permission-guarded API without checking state), missing fallback UI (screen renders blank instead of showing a re-request path), no path to Settings from a never-ask-again state, silent errors after a Settings-app revoke, missing rationale UI before prompt (which raises denial rates 30–50%), and state loss when app is killed mid-prompt.


