skip to content

Your Appium laundry pickup flow hands off to a separate courier app. How do you get both onto the device on Android and iOS?

level: seniorimportance: should knowfreq 42%

answer

  1. extra builds, not the app under test
  2. one path or a JSON array
  3. APK on Android, IPA or .app on iOS
  4. installed before the session starts
  5. installs but never adopts

basics

~20 s

Name the app under test with the app capability and the extra builds with appium:otherApps, which takes one path or URL or a JSON array of them. Android takes APK files, iOS takes IPA files or .app bundles.

solid answer

~40 s

`appium:app` still names the app under test - the laundry pickup build - and `appium:otherApps` carries everything else the session needs on the device. It accepts a single path or URL, or a JSON array of them, and each entry has to be a valid artifact for the platform: `.apk` or `.apks` for the Android drivers, a signed `.ipa` or a `.app` bundle for the XCUITest driver. The companions are put on the device before the session begins, which is what makes them usable by the time the first command runs. What `appium:otherApps` does not do is change which app the session is scoped to: the courier build is installed, not adopted, and identity capabilities such as `appium:appPackage` and `appium:bundleId` still describe the app under test alone.

go deeper

for a junior

Recall that appium:otherApps is how extra builds reach the device before a session, and that it is separate from app, which still names the one application the session is about.

for a middle

Explain the mechanics: a single value or a JSON array, resolved on the Appium server host, with APK entries for the Android drivers and IPA or .app entries for the XCUITest driver.

for a senior

Show you have run multi-app flows: the per-session install cost, keeping two platform-specific lists rather than one, and why a stale companion build can produce a passing run that proves nothing.

for a principal

Own the reproducibility argument: the capability set should fully state what a device must hold, so any worker or freshly imaged device can run the suite without hand preparation on either platform.

## The capability for extra builds A session often needs more than one application on the device. The laundry pickup app hands a collection off to a courier app; a test needs a helper build that fakes a partner integration; a flow crosses into a second first-party app and comes back. `appium:otherApps` is the capability that puts those extra builds on the device as part of session setup, and it exists on the Android drivers and on the XCUITest driver. It takes one of two shapes: - a single path or URL, when there is exactly one companion; - a JSON array of paths or URLs, when there are several. The same delivery rules apply as for `appium:app`: a filesystem path is resolved by the machine running the **Appium server**, and a URL is fetched by the server before the session starts. A path that exists only on the machine running your tests fails against a server on another host. ## Android and iOS artifacts, side by side | | Android drivers | XCUITest driver | |---|---|---| | companion artifact types | `.apk`, `.apks` | `.ipa`, or a `.app` bundle | | identity of the companion | not derived into any capability | not derived into any capability | | signing requirement | a signature the device will accept | signed for the target device, like any Apple build | | shape of a remote entry | a URL to the package file | a URL to a fetchable archive, since a `.app` is a directory | The asymmetry that catches people out is the last row. An Android package is a single file, so a URL to it is unremarkable. An Apple `.app` bundle is a directory, so a remote one has to arrive as something the server can fetch and unpack; an `.ipa` is the ordinary answer for a real device anyway. ## What otherApps does not do This is where most of the misunderstanding lives. `appium:otherApps` **delivers**; it does not **address**. - It does not change the app under test. `appium:app` and the identity capabilities still describe the laundry pickup build alone. - It does not register the companion's package name or bundle id anywhere in your capability set. If a step needs to address the courier app, you supply that identity yourself in the command that needs it. - It does not remove anything. Companion builds are added to the device; nothing about the capability implies a clean device afterwards. - It is not the way to install something once a session is already running. That is a different command family with its own semantics on each platform. ## The laundry pickup handoff, concretely For a suite whose pickup flow ends by launching the courier app: 1. `appium:app` names `laundry-pickup-release.apk` on Android, or `LaundryPickup.ipa` on iOS. 2. `appium:otherApps` names `courier-release.apk` on Android, or `Courier.ipa` on iOS - one entry, or a JSON array if a stub payments build joins them. 3. The session opens with both builds present, so the handoff step finds the courier app installed rather than failing on a device that never had it. The capability set is now a complete statement of what the device needed, which is worth more than it sounds: a new worker, a rebuilt emulator or a freshly wiped handset can run the suite without anyone remembering to pre-install a second build by hand. ## Cautions worth writing down - **Companion builds cost session start time on both platforms.** Every session installs every entry, so a long `appium:otherApps` list is a per-session tax across the whole run. - **Keep companion versions honest.** If a stale companion can produce a green run, make its delivery explicit and deliberate rather than assuming a session replaces whatever is already there. - **Each entry must be valid for the platform in play.** A cross-platform suite needs two lists, not one shared list - an `.apk` in an iOS session's `appium:otherApps` fails at install time. - **Do not use it as a general provisioning mechanism.** Certificates, media and configuration are not applications; `appium:otherApps` installs applications, and stretching it produces confusing failures. - **Remember it is session setup.** Anything that has to happen part-way through a run belongs in the commands that run during the session, not in this capability. ## Why it belongs with artifact and identity `appium:app`, `appium:otherApps` and the identity capabilities together answer one question: what does this device have to be holding before the first command is sent, and which of those things is the session about? Keeping the answer inside the capability set - for Android and for iOS separately, because the artifacts differ - is what makes a session reproducible on a device nobody prepared by hand.

  • What does appium:otherApps not do for the companion app?
    It does not make it the app under test. `appium:app` and the identity capabilities still describe the target build, and the companion's own package name or bundle id is not derived into your capability set - you supply it wherever a step needs to address that app.
  • How would you pass several companion builds at once on either platform?
    Give `appium:otherApps` a JSON array of paths or URLs instead of a single value. Both the Android drivers and the XCUITest driver accept the list form, and every entry has to be a valid artifact for that platform - APK entries for Android, IPA or .app entries for iOS.

saying these in an interview costs you the question

  • Thinks otherApps changes which app the session drives
  • Puts an .apk in an iOS session's otherApps list
  • Expects the companion's identity to appear in capabilities
  • Uses otherApps to install something mid-session
  • Assumes companions are removed when the session ends
  • Ignores the per-session install cost of a long list