How to Test Location Services in Mobile Apps (2026)

Location is one of the most sensitive permissions a user grants. It is also one of the most failure-prone features: GPS drift, permission edge cases, battery drain, background vs foreground, iOS vs An

January 17, 2026 · 3 min read · How-To Guides

Location is one of the most sensitive permissions a user grants. It is also one of the most failure-prone features: GPS drift, permission edge cases, battery drain, background vs foreground, iOS vs Android differences. This guide covers the test matrix.

Permission flows

  1. Location requested at feature use, not app launch
  2. Rationale clear before OS prompt
  3. Foreground-only permission offered first where possible
  4. Background permission requested separately with explicit justification
  5. Location-always (iOS) only requested when truly needed
  6. Approximate vs precise (Android 12+) choice respected

Location accuracy

  1. Feature works on approximate location (~100m)
  2. Feature requires precise only when necessary
  3. Accuracy degrades gracefully in poor GPS conditions
  4. Last-known location used as fallback when fresh fix unavailable
  5. Location-unavailable state shows clear UX ("Getting location...")

Foreground behavior

  1. Location updates while feature is visible
  2. Tracking pauses when feature exits (battery)
  3. Re-engages when feature re-enters
  4. Foreground frequency matches use case (1/sec for nav, 1/min for check-in)

Background behavior

  1. Background location use case visible to user
  2. Background updates at low power mode
  3. Geofence triggers fire reliably
  4. Background location pauses when app force-closed (Android 12+)
  5. Foreground service notification present if background location active

GPS edge cases

  1. Cold GPS → first fix within 30 seconds
  2. Indoor → degrades to cell / Wi-Fi fix
  3. Tunnel / underground → last-known with staleness indicator
  4. GPS spoof detected (if security-critical)
  5. Airplane mode → location disabled, clear message
  6. Mock location (dev option) detected

Battery

  1. Location updates at lowest useful frequency
  2. No continuous polling — use FusedLocationProvider (Android) or CoreLocation's efficient APIs (iOS)
  3. No background location if feature is not active
  4. Sleep / idle detection

iOS specifics

  1. NSLocationWhenInUseUsageDescription and related plist entries set
  2. Always authorization only after user has used feature with when-in-use first
  3. Precise vs reduced accuracy toggle handled (iOS 14+)
  4. Location arrow indicator visible in status bar when active

Android specifics

  1. ACCESS_FINE_LOCATION vs ACCESS_COARSE_LOCATION correctly requested
  2. ACCESS_BACKGROUND_LOCATION requested separately (Android 10+)
  3. Foreground service type location declared
  4. Battery optimization exemption requested only with strong justification

Edge cases

  1. Location permission granted then system-wide location disabled → handled
  2. Airplane mode then back online → location resumes
  3. Cell-only device (no GPS) → Wi-Fi and cell triangulation used
  4. Multi-user device (work profile) → per-user permission
  5. Timezone / DST edge cases for location-based time features
  6. User changes location provider priority → respected

Accessibility

  1. Current location announced by screen reader (e.g., "Centered on 123 Main St")
  2. Location-required CTAs clearly labeled
  3. Alternative (manual address entry) offered for denied users

Privacy

  1. Location not logged with user identifier unnecessarily
  2. Location not shared with third-party analytics at precise level
  3. User can export or delete location history
  4. Location rounded / obfuscated for display to other users
  5. No location in URL parameters

Manual testing

Use a physical device. Test in varied conditions:

Automated testing

Android


// Mock location
val provider = LocationManager.GPS_PROVIDER
locationManager.addTestProvider(provider, false, false, false, false, true, true, true, 0, 1)
locationManager.setTestProviderEnabled(provider, true)
val location = Location(provider).apply { latitude = 37.7749; longitude = -122.4194 }
locationManager.setTestProviderLocation(provider, location)

iOS


// Simulate a location in Xcode scheme: Edit Scheme → Run → Options → Default Location
// Or programmatically in UITests

How SUSA tests location

SUSA can fire mock-location intents on Android emulators and verify app behavior at multiple coordinates (airport, city, remote area). Personas:


susatest-agent test mapapp.apk --persona adversarial --location 40.7128,-74.0060

Common production bugs

  1. App freezes on cold start while waiting for first GPS fix
  2. Background location drains battery due to continuous high-accuracy updates
  3. Location permission prompted at launch before user understands use
  4. Location mismatch with timezone — app uses device timezone, backend assumes IP geolocation
  5. Stale location served from cache for minutes after user has moved

Location is sensitive, complex, and high-impact. Test every release. Real-device GPS testing is mandatory.

Test Your App Autonomously

Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts.

Try SUSA Free