iOS vs Android — Key Differences for Testers

8 min read

iOS and Android look similar to users. To a tester, they are entirely different operating systems with different permission models, different accessibility frameworks, different file systems, and different automation engines. Knowing the distinctions before you write your first test prevents a class of bugs that beginners waste days chasing.

The automation engines

Appium does not drive iOS and Android directly. It delegates to the platform's native automation framework.

Android — UIAutomator2

UIAutomator2 is Google's accessibility-based automation library. It runs as a separate process on the device and communicates with the Appium server over ADB. Because it sits at the accessibility layer, it can interact with any visible element — including system dialogs outside your app.

iOS — XCUITest

XCUITest is Apple's test framework, bundled with Xcode. Appium wraps it through WebDriverAgent (WDA), a thin XCUITest application that Appium signs and installs on the target device. WDA runs on the device and exposes a WebDriver-compatible HTTP server. All Appium commands to iOS flow through WDA.

The practical implication: iOS automation requires a Mac with Xcode installed. Android can be automated from any OS (macOS, Windows, Linux) because ADB is platform-agnostic.

Locator differences

The element attributes exposed by each platform differ:

AttributeAndroidiOS
Unique IDresource-id (e.g., com.app:id/login_button)accessibilityIdentifier
Human labelcontent-descaccessibilityLabel
Visible texttextlabel or value
Element typeFull class name (e.g., android.widget.Button)XCUIElement type (e.g., XCUIElementTypeButton)

Accessibility ID maps to content-desc on Android and accessibilityIdentifier / accessibilityLabel on iOS, making it the most portable cross-platform locator strategy.

Permission models

Both platforms require user consent before an app can access sensitive resources, but they behave differently in automation.

Android permissions can be granted at install time via ADB:

adb shell pm grant com.myapp.package android.permission.ACCESS_FINE_LOCATION

This prevents the dialog from appearing during the test entirely, which is the cleanest approach. You can also interact with the dialog through UIAutomator2 since it has system-level access.

iOS permission dialogs are system UI that require the user (or your test) to tap "Allow" or "Don't Allow." In Appium, you handle them with either:

  • driver.executeScript("mobile: alert", Map.of("action", "accept")) for simple alerts
  • A dedicated PermissionsHelper using mobile: setPermission (iOS 15+)
  • Explicitly granting permissions in the Simulator via xcrun simctl privacy

App installation and reset

Android: APK files are installed directly. During tests, you can clear all app data without reinstalling:

adb shell pm clear com.myapp.package

Appium also exposes this as driver.terminateApp(bundleId) + driver.executeScript("mobile: clearApp", ...).

iOS: Simulator tests use .app bundles installed via xcrun simctl. Real device tests use signed .ipa files. Clearing app data on iOS requires reinstalling or using the mobile: clearApp Appium command (Simulator-only).

Fragmentation

Android has severe fragmentation. Thousands of device models run different Android versions with different OEM customisations. Samsung One UI, MIUI, Huawei EMUI, and stock Android all have different permission dialogs, different default fonts, and different behaviour for things like floating windows and back gestures.

iOS is the opposite: Apple controls both hardware and software. There are fewer than 20 actively supported iPhone models at any time, all running the same iOS build. Tests written for one iPhone generally work on all current iPhones.

This difference shapes device strategy:

  • iOS: a small matrix (latest and one-prior iOS version, one iPhone size)
  • Android: a larger matrix (several Android versions, one or two OEM skins, multiple screen densities)

Back navigation

Android has a hardware or gesture back button. Tests can trigger it with driver.pressKey(new KeyEvent(AndroidKey.BACK)).

iOS has no hardware back button. Navigation relies entirely on app-level back buttons or swipe gestures. Your iOS tests must interact with the in-app back button element rather than using a system key press.

Simulator vs Emulator

The naming is deliberate and matters:

  • Android Emulator — full x86 system emulation; slower but accurate
  • iOS Simulator — not true emulation; it runs iOS app code compiled for the Mac's CPU. Fast, but some device behaviours (hardware sensors, GPS realism, certain network conditions) differ from a real device

Both are covered in depth in the next lesson.

// tip to track lessons you complete and pick up where you left off across devices.