Skip to content
QSWEQB
mediumConceptScenarioEntryMidSenior

What makes testing a mobile app different from testing a web application?

Mobile adds four things a browser mostly hides: a device and OS matrix you cannot enumerate, a network that degrades and disappears mid-request, an operating system that interrupts and revokes permissions at will, and hardware behaviour that emulators cannot reproduce.

6 min readUpdated 2026-07-26

What the interviewer is scoring

  • Whether the device matrix is derived from your own analytics rather than from a list of popular phones
  • Does the candidate name lifecycle and process-death bugs, which are the ones manual testing never reaches
  • That degraded and intermittent networks are treated as a test condition, not as an environment problem
  • Whether permissions are tested in the revoked and mid-session-changed states, not only at first launch
  • Does the candidate say what an emulator is genuinely good for, instead of dismissing it

Answer

The matrix has no bottom

A web application runs in perhaps five browser engines you can name. A mobile app runs on a combination of operating system version, manufacturer, device model, screen size and density, available memory, and manufacturer firmware modifications, and the combinatorial space is large enough that enumerating it is not a strategy. The useful skill is not knowing that fragmentation exists, it is choosing a small set of devices you can defend.

Derive that set from your own install base rather than from a market-share article. Take your analytics and pick, deliberately, the highest-volume device, the oldest OS version you still support, the smallest screen and the largest, one low-memory device, and one from each manufacturer whose firmware is known to behave differently. Then say what you are choosing not to cover, because an untested tail you have named is manageable and an untested tail you have not is a surprise.

The two platforms fragment differently, and saying so is a real signal. On Android the OS version spread is wide and manufacturer firmware changes behaviour that the platform documentation says is fixed, most notoriously aggressive battery management that terminates background work the OS contract says should run. On iOS version adoption is fast and firmware is uniform, so the variance moves elsewhere: screen geometry and safe-area insets, device generation for performance, and the fact that a single OS release can change a system behaviour for almost your entire user base overnight.

There is a third axis that has no web equivalent: your own app versions. Users do not refresh a mobile app. Some proportion of them will be running the build you shipped eleven months ago for as long as it keeps working, which means every server change has to remain compatible with old clients and every local database change needs a migration path tested from several starting versions, not just from the previous one.

The network is a variable, not a given

Web testing usually happens on a stable connection and treats a network failure as an infrastructure incident. Mobile testing has to treat the network as an input with a range, because the app will spend real time on a train, in a lift, and on hotel wifi that resolves DNS but drops every other packet.

Test at least four network states as first-class conditions. Full offline, where the question is whether the app degrades to cached content with an honest message or shows a spinner forever. High latency with low bandwidth, where the question is whether timeouts are set sensibly and whether the user can queue an action rather than being blocked. Intermittent loss, which is where duplicate submissions come from, because a request that succeeded on the server but whose response never arrived will be retried by a client that does not use an idempotency key. And the handover case, where the device switches from wifi to cellular mid-request and the socket dies while the app believes it is still connected.

The captive portal deserves its own mention because it defeats naive connectivity checks. The device reports a working connection, DNS resolves, and every request returns a login page with a 200 status, so an app that decides it is online by checking the radio state will happily parse HTML as JSON.

Interruptions and permissions are the OS asserting control

On mobile the operating system, not the user, decides when your app stops. An incoming call, a notification pulled into full screen, the biometric prompt from another app, the user switching away and coming back twenty minutes later, and low-memory termination of your backgrounded process are all normal events, and each one is a chance for the app to lose state.

Process death is the highest-value case and the one manual testers almost never reach, because a human tester stays inside the app. The bug it produces is severe and specific: the user is halfway through a form, backgrounds the app to check something, the OS reclaims the process, and on return the app is recreated from scratch with the form empty or, worse, half-populated from a stale saved state. You can force this deliberately, which is why there is no excuse for not testing it.

# Android: make every activity destroy on background, so any state
# not properly saved and restored breaks immediately.
adb shell settings put global always_finish_activities 1

# Simulate the low-memory signal the OS sends before it kills you.
adb shell am send-trim-memory com.example.app RUNNING_CRITICAL

Permissions are the other place the OS intervenes, and the states that matter are the ones after the first launch. Since Android 6.0 permissions are requested at runtime and can be denied, denied permanently, or revoked later from settings while the app is installed and running. On iOS the equivalents include location granted only once, notifications declined, and the tracking prompt introduced in iOS 14.5. The test cases are therefore: never asked, granted, denied once, denied with "don't ask again", and revoked from settings while the app was in the background. The last one produces the most crashes, because code written on the assumption that a permission granted at startup stays granted will dereference a null camera or query a location provider that now throws.

Real devices and emulators answer different questions

Framing this as a trade-off to be won by one side is the weaker answer. They are tools for different jobs and a sensible pipeline uses both.

Emulators and simulators are fast, disposable, scriptable, and cheap to run many of in parallel, which makes them right for functional regression, cross-OS-version checks, and everything running on every commit. They also make some hard cases easy: you can set an arbitrary locale, force a specific screen density, or shape the network far more conveniently than with a real handset.

What they cannot tell you is anything that depends on real hardware or real firmware. Performance and battery and thermal behaviour are meaningless on a simulator backed by a desktop CPU. Camera, sensors, GPS with real satellite acquisition, biometrics, Bluetooth, and NFC are either stubbed or absent. Push notification delivery through the real carrier and OS path, behaviour under a genuine cellular network, and manufacturer firmware quirks all require the physical device. Crucially, so does anything about how the app feels: touch responsiveness, scroll smoothness, and keyboard behaviour over a real layout.

So the split is: emulators for breadth and for the per-commit suite, a small rack of real devices or a device cloud for the release pack, and real devices exclusively for performance, hardware features, and final visual verification. When someone reports a bug you cannot reproduce on the emulator, the reasonable first hypothesis is that the emulator is the reason.

Where this answer usually stays shallow

The word "fragmentation" is where most candidates stop, and it is nearly free to say. What separates a strong answer is naming the class of bug that mobile has and web mostly does not, which is state loss across an OS-driven lifecycle transition. Fragmentation causes visual and compatibility defects that are annoying and usually obvious. Lifecycle and permission-revocation defects cause data loss and crashes, they only appear in usage patterns nobody scripts, and they are entirely reproducible on one device with two developer settings turned on. A candidate who has actually shipped a mobile app talks about the second category unprompted.

Likely follow-ups

  • How would you choose six devices for a release regression pack?
  • A crash only reproduces on one manufacturer's phones. How do you investigate?
  • How do you test that the app behaves correctly when the OS kills it in the background?
  • What changes about your test approach when 30 percent of users are still on a version you shipped a year ago?

Related questions

mobile-testingdevice-fragmentationappiumnetwork-conditionsapp-lifecycle