skip to content

Install and Removal

Putting a build on a target and taking it off again: the install, remove and is-installed commands on Android and on iOS, plus the artifact format each platform accepts. Suite setup fails here first.

on this pageshow

explore

questions

5

In Appium, which execute methods install and remove a build on Android and on iOS?

level: juniorimportance: should knowfreq 70%

answer

  1. same three names on both
  2. install, remove, is-installed
  3. declared in different drivers
  4. artifact and identifier diverge
  5. package name versus bundle id

basics

~20 s

Both platforms use the same three execute methods: mobile: installApp puts a build on the target, mobile: removeApp takes it off, and mobile: isAppInstalled reports whether it is there. The artifact and the identifier you pass differ per platform.

solid answer

~40 s

The names are shared. On Android `mobile: installApp`, `mobile: removeApp` and `mobile: isAppInstalled` come from `appium-android-driver`, the base driver that the UiAutomator2 and Espresso drivers both extend. On Apple platforms the XCUITest driver declares its own methods with the same three names. What differs is what you hand them: to install, an `.apk` or `.apks` on Android versus an `.ipa` or `.app` on Apple platforms; to remove or check, the app's own identifier, which is a package name on Android and a bundle id on Apple platforms. All three are execute methods posted to a live session, so they act on the beekeeping hive-log build mid-run, not only at session start.

go deeper

for a junior

Learn the three names and that they are the same on both platforms: mobile: installApp, mobile: removeApp and mobile: isAppInstalled. Know that the artifact you pass differs by platform.

for a middle

Explain where the names come from — the shared Android base driver on one side, the XCUITest driver's own map on the other — and why identity is a package name on Android and a bundle id on Apple platforms.

for a senior

Show how you make setup idempotent with these three commands, and say plainly what the is-installed check does not prove about which build is on the device.

for a principal

Be ready to argue where install belongs across a fleet and a pipeline, and what a suite should record about it so a cross-platform failure can be attributed without re-running anything.

## Three commands, and the names are shared Appium exposes app installation as **driver execute methods** posted to a live session, rather than as a set of bespoke HTTP verbs you learn separately. Three of them cover putting a build on a target and taking it off again, and they carry the same names on Android and on Apple platforms: - `mobile: installApp` — put a build on the target. - `mobile: removeApp` — take an installed app off it. - `mobile: isAppInstalled` — report whether an app with a given identifier is present. The shared naming is genuinely convenient, and it is also the trap on this subject: the same name does not imply the same machinery, the same artifact, or the same argument. ## Where each name is actually declared On Android the three come from **`appium-android-driver`**, the base driver that the UiAutomator2 and the Espresso drivers both extend, so a session on either driver has them. On Apple platforms the **XCUITest driver** declares its own `mobile: installApp`, `mobile: removeApp` and `mobile: isAppInstalled` in its own execute-method map, alongside the rest of its app lifecycle surface and `mobile: listApps`. Two habits follow from that, and both are worth forming early: - Attribute a command to the right driver family. Saying *the UiAutomator2 driver's `mobile: installApp`* reads as true and is not, because the method comes from the shared Android base. - Never assume a command exists on the other platform because you found it on this one. UiAutomator2's `mobile: installMultipleApks`, for split builds, has no Apple counterpart at all. ## What you pass them is not the same To install, you supply an artifact, and the platforms accept different ones. To remove or to check, you supply the app's own identifier, and the platforms spell identity differently — a package name on Android, a bundle id on Apple platforms. | | Android | Apple platforms | |---|---|---| | declared by | `appium-android-driver`, inherited by UiAutomator2 and Espresso | the XCUITest driver's own execute-method map | | install artifact | `.apk`, or an `.apks` archive carrying a split set | `.ipa` archive, or an `.app` bundle | | multi-artifact install | UiAutomator2's `mobile: installMultipleApks` | none | | identity passed to remove or check | the package name | the bundle id | That table is the honest shape of the subject: one vocabulary, two mechanisms. Which capabilities name an artifact or an identity when the **session starts** is a separate subject; these three methods are what you call once a session is already running. ## The endpoints did not disappear Appium 3 moved a great deal of the old `/appium/...` surface into per-driver execute methods, and the app-management routes are a measured exception. `install_app`, `remove_app` and `app_installed` are still declared in the core route table, under `/session/:sessionId/appium/device/`. The `mobile:` execute methods are the richer, per-driver surface — more options and driver-specific behaviour — but a client that still calls those routes is not calling something that was deleted. Note the spelling too: the source writes `:sessionId`, never `:id`. ## Using them without lying to yourself - Make setup **idempotent**: check with `mobile: isAppInstalled`, remove with `mobile: removeApp` if you need a clean slate, then install. A step that assumes a virgin device fails on the second run of the day. - Remember what the check proves. `mobile: isAppInstalled` answers whether that identifier is present — not whether the build behind it is the one your pipeline just produced. - Keep install out of the assertion path. It belongs in setup, where a failure reads as a setup failure rather than as a broken hive-log feature. - Expect install to cost real time on hardware, and to cost more the larger the artifact. It is the first thing a mobile suite does and the most common place a suite appears to stall. - Log which artifact path went to which target. When two lanes disagree, that line answers the question faster than any screenshot. For a beekeeping hive-log suite this means one small, boring setup helper: is the app there, do we want it gone, put the right artifact on, and record what we did. Everything platform-specific about it lives in the artifact and the identifier, not in the command names.

  • Does mobile: isAppInstalled returning true mean the target has the build you just produced?
    No. It answers only whether an app with that identifier is present. A stale build carrying the same package name or bundle id satisfies it, and on Android a partially installed split set satisfies it too. If you need to know the build is current, remove and reinstall, or verify a version the app itself reports.
  • If the core still declares install_app and remove_app routes, why call the mobile: methods at all?
    Because the execute methods are the richer per-driver surface: they carry driver-specific options and behaviour the generic routes do not expose, and UiAutomator2's split-install command has no route equivalent at all. The routes are a live, simpler path rather than a deprecated one, but new work should reach for the driver's method.

saying these in an interview costs you the question

  • Thinks Appium has different install command names per platform
  • Passes an apk path to an Apple session
  • Believes Appium 3 deleted the app-management routes
  • Treats isAppInstalled as proof the build is current
  • Writes endpoints as /session/:id instead of :sessionId
open as a page

In Appium, what actually happens when mobile: installApp runs on Android versus iOS?

level: middleimportance: should knowfreq 55%

basics

~20 s

On Android the drivers hand the artifact to their adb layer, which transfers it and drives the platform package installer. On Apple platforms the XCUITest driver installs through simctl for a simulator and devicectl for a real device.

open as a page

Your Appium hive-log build fails to install on a real Android phone and on a real iPhone. How do you triage each?

level: seniorimportance: should knowfreq 46%

basics

~20 s

Separate the artifact from the target. On Android, check the build's shape and remove a conflicting package before retrying. On an iPhone, check the artifact is a device build rather than a Simulator one, and that the driver reaches the device.

open as a page

In an Appium suite spanning Android and iOS, how do you design one install-and-remove step?

level: principalimportance: should knowfreq 40%

basics

~20 s

Keep one verb in the suite and one adapter per platform. The command names match on Android and Apple platforms, so what an adapter varies is the artifact, the app identifier, and whether split APKs need UiAutomator2's multi-apk install.

open as a page

In Appium, when does an Android install need mobile: installMultipleApks instead of mobile: installApp?

level: seniorimportance: nice to knowfreq 34%

basics

~20 s

Use it when an Android build ships as separate split APKs rather than one file. UiAutomator2's mobile: installMultipleApks lands the whole split set in one transaction; mobile: installApp takes a single artifact, and Apple platforms have no multi-artifact twin.

open as a page