skip to content

Emulators and Simulators

Getting a session onto an emulator or a simulator, which is a different toolchain and a different capability set on each platform, and knowing what a virtual target can never show you.

on this pageshow

explore

questions

5

In Appium, how does a session get onto an Android emulator versus an Apple simulator?

level: juniorimportance: must knowfreq 70%

answer

  1. two toolchains, not one
  2. an AVD name on one side
  3. simctl boots the Apple side
  4. macOS with Xcode for simulators
  5. avd versus simulatorStartupTimeout

basics

~20 s

Two different toolchains. On Android the drivers launch or attach to a named AVD and reach it over adb like any other Android target. On Apple the XCUITest driver boots a simulator with simctl, which requires a macOS host with Xcode.

solid answer

~40 s

On Android, `appium:avd` names an AVD that already exists on the host. If it is not running the Android drivers start it — `appium:avdArgs` and `appium:isHeadless` shape that launch — and from then on the emulator is addressed over adb exactly like a physical phone. On Apple there is no AVD name: the XCUITest driver selects and boots a simulator through **`simctl`**, Xcode's simulator-control tool, waits up to `appium:simulatorStartupTimeout` for it, then builds and installs **WebDriverAgent** with `xcodebuild`. That is why an Apple simulator lane needs macOS with Xcode while an Android emulator lane does not. The two capability sets do not overlap — `appium:avd` means nothing to XCUITest.

code

json · 16 lines
json
{
  "androidEmulatorLane": {
    "platformName": "Android",
    "appium:automationName": "UiAutomator2",
    "appium:avd": "fitting_lab_avd",
    "appium:isHeadless": true,
    "app": "/builds/hearing-aid-fitting.apk"
  },
  "appleSimulatorLane": {
    "platformName": "iOS",
    "appium:automationName": "XCUITest",
    "appium:deviceName": "iPhone",
    "appium:simulatorStartupTimeout": 180000,
    "app": "/builds/HearingAidFitting.app"
  }
}

go deeper

for a junior

Be ready to name the two toolchains: an AVD name on the Android side, simctl on the Apple side. Knowing that the two capability blocks do not overlap is most of the answer at this level.

for a middle

Explain what happens between the session request and the first command on each platform: launching or attaching to the emulator over adb, or booting a simulator and then building WebDriverAgent with xcodebuild.

for a senior

Show that you budget for it. Cold boots are the slowest part of a virtual-target run, and appium:simulatorStartupTimeout decides whether a slow simulator boot fails the session or merely delays it.

for a principal

Own the asymmetry: an Apple simulator lane is pinned to a macOS host with Xcode while an Android emulator lane is host-agnostic. That constraint shapes how the two halves of a suite are supplied with machines.

## Two words that are not synonyms An Android **emulator** and an Apple **simulator** are different technologies reached through different toolchains, and Appium treats them accordingly. Everything a session needs in order to *start* diverges: which capability names the target, which host tool boots it, how long the driver waits, and what agent it installs afterwards. Once the target is up the session looks the same on both sides — the same W3C endpoints, the same finds, the same teardown. The divergence is concentrated in the first few seconds, and that is exactly the part people get wrong. ## The Android path: name an AVD, let the driver launch it On Android the driver is chosen with `platformName: Android` plus `appium:automationName` (`UiAutomator2` or `Espresso`), and the virtual target is named with **`appium:avd`** — the name of an Android Virtual Device that already exists on the host. Two launch-shaping capabilities ride alongside it: - **`appium:avdArgs`** — extra command-line arguments handed to the emulator when the driver launches it. - **`appium:isHeadless`** — start the emulator with no window on the host, which is what you want on a machine with no display attached. Creating that AVD in the first place — picking a device profile, installing a system image, enabling hardware acceleration — happens before Appium is in the picture and is not part of the session. Appium's job starts at "an AVD by this name exists": if it is not running the Android drivers start it, and if it is already running they use it. That is why the launch-shaping capabilities only bite when the driver is the one doing the launching. After boot the emulator is just another Android target. The drivers reach it over adb exactly as they would a physical phone, push and start the on-device helper server, install the build and begin answering commands. Nothing downstream of the boot knows the target is virtual. ## The Apple path: boot with simctl, then build the agent On Apple the driver is chosen with `platformName: iOS` plus `appium:automationName: XCUITest`, and there is no AVD name to give. The XCUITest driver selects and boots a simulator through **`simctl`**, Xcode's command-line simulator-control tool. Its real-device counterpart is `devicectl`; the two address different classes of target and are not interchangeable. **`appium:simulatorStartupTimeout`** bounds how long the driver waits for that boot before failing the session, and a cold boot on a busy machine is one of the slowest things in a whole run. Booting is only half of it. The XCUITest driver drives the UI through **WebDriverAgent**, an agent that has to be built and installed onto the target with `xcodebuild` before any command can be answered. Both `simctl` and `xcodebuild` are Xcode tooling, so an Apple simulator session requires a **macOS host with Xcode**. This is the hard edge of the subject: the XCUITest driver's limited support for Windows and Linux hosts covers real devices only, because simulators can only be run on macOS. ## The two paths side by side | | Android emulator | Apple simulator | |---|---|---| | Names the target | `appium:avd` | Apple-side selection keys, never an AVD name | | Booted by | the SDK's emulator tooling, then reached over adb | `simctl` | | Launch shaping | `appium:avdArgs`, `appium:isHeadless` | no equivalent argument passthrough | | Boot budget | the driver's own launch waits | `appium:simulatorStartupTimeout` | | Agent after boot | helper server pushed to the device | WebDriverAgent built with `xcodebuild` | | Host requirement | any host the Android SDK runs on | macOS with Xcode | ## Practical consequences for a fitting-app suite - Write two capability blocks rather than one with conditionals: `appium:avd` has no Apple key it maps onto. - Budget the Apple lane's session start separately — building WebDriverAgent is real work the Android side has no equivalent of. - Expect the first session on a cold machine to be the slow one on both platforms, and do not read that as a defect in the app under test. - Keep the artifact per platform; the build you install is a different file on each side. - If the host must open no windows, `appium:isHeadless` covers the Android launch — verify what your Apple lane actually does rather than assuming symmetry between the two. ## When it fails, it fails before your first command A virtual-target failure almost always lands before the test body runs: the AVD name is not one that exists on this host, the emulator never reports ready, the simulator boot outruns `appium:simulatorStartupTimeout`, or the WebDriverAgent build fails on a host without Xcode. Reading such a failure as "the boot stage" rather than "the test" is what makes it quick to fix — the capability block, not the page object, is where the bug is.

  • Which host does an Apple simulator session require, and why?
    macOS with Xcode. The XCUITest driver boots the simulator through `simctl` and builds WebDriverAgent with `xcodebuild`, both of which are Xcode tooling, and simulators do not exist on Linux or Windows at all. An Android emulator lane carries no such constraint — the Android drivers run wherever the Android SDK does.
  • If the AVD named by appium:avd is already running, what changes?
    The Android drivers use the emulator that is already up rather than starting a second one, so the launch-shaping capabilities — `appium:avdArgs`, `appium:isHeadless` — have nothing left to influence. Treat them as launch-time-only knobs: to change them, let the driver own the emulator's lifecycle instead of handing it one that is already booted.

Think of the Android emulator as a guest machine you switch on and then talk to like any phone, and the Apple simulator as something Xcode brings up on the Mac itself — which is why one is reached over adb and the other through Xcode's own tooling.

saying these in an interview costs you the question

  • Thinks one capability set boots both an emulator and a simulator
  • Says appium:avd also selects an Apple simulator
  • Assumes an Apple simulator can be booted on a Linux host
  • Believes the driver never launches the emulator itself
  • Treats emulator and simulator as interchangeable words
open as a page

In Appium on Android, what do appium:avdArgs and appium:isHeadless change about the emulator it starts?

level: middleimportance: should knowfreq 45%

basics

~20 s

Both shape the emulator launch the Android drivers perform. avdArgs passes extra command-line arguments to the emulator binary; isHeadless starts it with no window on the host. Both apply only when the driver is the one launching the AVD.

open as a page

In Appium, how can a test drive the emulator or simulator itself rather than the app under test?

level: middleimportance: should knowfreq 38%

basics

~20 s

Through driver execute methods aimed at the virtual machine, not the UI. The Android drivers expose mobile: execEmuConsoleCommand for a running emulator's console channel; the XCUITest driver exposes mobile: simctl for a booted Apple simulator.

open as a page

In Appium, which driver commands need an Android emulator or Apple simulator, and which refuse one?

level: seniorimportance: should knowfreq 44%

basics

~10 s

Support is a property of the individual method, not of the platform. Some commands need a virtual target and some need physical hardware, and both cases occur on both platforms. Check per method.

open as a page

How would you shape Appium capability profiles when one lane runs Android emulators and another Apple simulators?

level: principalimportance: should knowfreq 32%

basics

~10 s

Start from how little is genuinely shared. Keep one small common block, then two honest platform blocks: the Android emulator launch keys, and the Apple simulator boot budget. Hide nothing.

open as a page