Skip to content
Innovialabs

How to Test a Mobile App: Manual, Automated and Device Farms

Practice3 min

In short

A reliable setup is many fast unit tests, fewer UI component tests and a handful of end-to-end flows, plus manual checks before release. Emulators are fine for daily development, while real devices and cloud farms verify the app on what your users actually own.

The short answer: the test pyramid

A mobile app is tested on three levels:

  • Unit tests — many, fast, checking logic without UI.
  • UI component tests (widget tests in Flutter) — fewer, checking screens and elements.
  • End-to-end (E2E) — a few, checking key flows end to end: sign-in, payment, checkout.

On top of automation sits manual testing: exploring new features and regression before release.

Test levels

LevelWhat it checksSpeedWhen to run
UnitBusiness logic, calculations, data mappingSecondsOn every commit
UI components / widgetScreen rendering, taps, statesFastOn every pull request
E2EA flow from launch to result, with network and navigationSlowOn pull requests or nightly

The higher the level, the more a test costs to maintain and the more often it turns flaky. Cover core logic at the bottom and keep E2E for the most important paths.

Tools

ToolPlatformUsed for
XCTest / XCUITestiOSUnit and UI tests, built into Xcode
EspressoAndroidIn-process UI tests, synchronized with the main thread
flutter_test, integration_testFlutterUnit, widget and integration tests
DetoxReact NativeGray-box E2E: waits until the app is idle
MaestroiOS, Android, cross-platformE2E flows in YAML, quick to start without deep code knowledge
AppiumiOS, AndroidCross-platform E2E via WebDriver

A Maestro flow example:

appId: com.example.app
---
- launchApp
- tapOn: "Sign in"
- inputText: "test@example.com"
- tapOn: "Continue"
- assertVisible: "Home"

Manual testing

Automation doesn't fully replace people. Check manually:

  • new features — exploratory testing while flows are still changing;
  • visual details: fonts, spacing, dark mode, different screen sizes;
  • interruptions: an incoming call, backgrounding the app, losing network, denied permissions;
  • checklist regression before each release.

Distribute builds to testers via TestFlight on iOS and internal testing in Google Play Console.

Emulators or real devices

Emulators and simulatorsReal devices
CostFreeMust be bought or rented
StartupFast, CI-friendlySlower to set up
AccuracyDon't reproduce real performance, camera, sensorsReal behavior, vendor skins
Use forDaily development, unit and UI testsPre-release checks, performance, hardware

Real Android devices matter most: vendor skins handle background work, notifications and battery saving differently.

Cloud device farms

If buying a fleet of phones is too expensive, use a farm: Firebase Test Lab, AWS Device Farm, BrowserStack, Sauce Labs. They run your tests on real devices in the cloud and return logs, videos and screenshots.

How to pick devices:

  • Take the most popular models and OS versions among your users from analytics.
  • Add your minimum supported OS version.
  • Include a small screen and a low-end device with little memory.

Common mistakes

  • Fixed sleep pauses instead of waiting for a state — the main source of flaky tests.
  • Testing only the happy path, without network errors or empty data.
  • Checking the app only on the developer's own phone.
  • Running E2E by hand instead of in CI, so they get forgotten.

FAQ

Unit tests for the riskiest logic: price calculations, authentication, data handling. Then add one or two E2E flows for the main scenario, such as sign-in and checkout.

We can help with this

If you'd rather get the result than figure it all out yourself — this is what we do every day.

Discuss a project

Read next

Have an idea or a task? Tell us about it

We'll reply within one business day and propose a solution. The consultation is free.