skip to content

Application Under Test

What the driver is told to run — an Android package or an iOS bundle, an artifact on disk or something already installed — and what it may do to that app before the first command.

on this pageshow

explore

questions

8

In Appium on iOS, which capabilities sign WebDriverAgent for a real device?

level: juniorimportance: must knowfreq 60%

answer

  1. the agent is an app too
  2. a device refuses unsigned code
  3. team, identity, bundle identifier
  4. appium:xcodeOrgId carries the Team ID

basics

~20 s

Three XCUITest capabilities: appium:xcodeOrgId names the Apple Developer team, appium:xcodeSigningId names the signing identity, and appium:updatedWDABundleId rebuilds the agent under a bundle identifier your provisioning profile covers. Android has no equivalent, because it has no provisioning profile.

solid answer

~40 s

On a real Apple device the XCUITest driver installs **WebDriverAgent** as an application, and the device will not launch an application that is not signed and provisioned for it. So the driver takes its signing configuration from capabilities. `appium:xcodeOrgId` carries your Apple Developer Team ID. `appium:xcodeSigningId` names which signing identity is used; a test agent is signed for development, not for distribution. `appium:updatedWDABundleId` rebuilds the agent under a bundle identifier your team's provisioning profile actually covers, which matters because the agent's stock identifier belongs to the upstream project rather than to you. A simulator session needs none of this. Android has no capability of this shape at all: its signing capabilities act on the app under test instead.

code

json · 12 lines
json
{
  "capabilities": {
    "alwaysMatch": {
      "platformName": "iOS",
      "appium:automationName": "XCUITest",
      "appium:xcodeOrgId": "AB12CD34EF",
      "appium:xcodeSigningId": "Apple Development",
      "appium:updatedWDABundleId": "com.example.snowploughdispatch.WebDriverAgentRunner"
    },
    "firstMatch": [{}]
  }
}

go deeper

for a junior

Be able to name the three signing capabilities and say what each one holds: a team identifier, a signing identity, and a bundle identifier for the agent. Knowing they bite only on real Apple devices is enough at this stage.

for a middle

Explain why the agent needs signing at all, namely that it is a separate application the driver installs, and why changing its bundle identifier is what lets a team provisioning profile cover it.

for a senior

Show how you keep a real-device iOS lane's signing configuration stable across hosts and rebuilds, and how you separate an agent-signing problem from an app-under-test problem instead of guessing between them.

for a principal

Own the question of who supplies the team identity that test agents are signed with, and whether real-device iOS coverage earns the signing upkeep it adds to every lane that uses it.

## Why an iOS session has a signing problem at all Appium's XCUITest driver does not drive an iPhone from the outside. It ships a companion application, **WebDriverAgent**, builds it with `xcodebuild` on a macOS host, installs it on the target, and then speaks HTTP to it. Every find, every tap and every page-source read in an iOS session is answered by that agent running on the device. That architecture is what creates the signing requirement. A physical Apple device will only launch an application that carries a valid code signature and a provisioning profile permitting it to run on that particular device. Your snowplough dispatch build has to satisfy that rule, and so does the agent. But the agent is not your build; it is Appium's. Somebody has to sign it with an identity your team controls, and the three capabilities below are how a session tells the driver which identity that is. An Apple simulator does not enforce the same rule, which is why an iOS lane can run happily for months against simulators and then stop the first time it is pointed at real hardware: the signing configuration was never needed before. ## The three capabilities | Capability | What you put in it | What it changes | | --- | --- | --- | | `appium:xcodeOrgId` | your Apple Developer **Team ID** | which team the agent is signed under | | `appium:xcodeSigningId` | the name of a signing identity | which identity signs the agent build | | `appium:updatedWDABundleId` | a bundle identifier your team owns | the identifier the agent is rebuilt and installed under | Read in order, they answer three different questions: 1. **Who is signing?** `appium:xcodeOrgId` carries the Apple Developer Team ID. Without a team there is no certificate to sign with, so this is the one a real-device lane can never leave out. 2. **With what kind of identity?** `appium:xcodeSigningId` names the identity itself. A test agent is signed for development rather than for distribution, so this is the capability that is set least often and changed least. 3. **Signing what, exactly?** `appium:updatedWDABundleId` is the one people meet last. The agent's stock bundle identifier belongs to the upstream WebDriverAgent project, and a team's provisioning profile normally does not cover an identifier the team does not own. Rebuilding the agent under an identifier your own profile does cover is what makes the install legal. ## Where the values come from, and what they are not - The Team ID is a property of the Apple Developer account, not of the device and not of the build. Every real device the dispatch lane touches has to be covered by a profile under that same team. - The identifier you give `appium:updatedWDABundleId` is the **agent's**, not the app under test's. The two sit side by side on the device as separate applications, and confusing them is the most common misreading of this capability. - None of the three touches the snowplough dispatch application itself. The XCUITest driver signs the agent; your application arrives already signed by whatever produced it, and the driver installs it as it is. ## Android does not have this problem, it has a different one The mirror image is worth stating precisely, because *Android needs no signing* is wrong. | | iOS, XCUITest driver | Android, UiAutomator2 and Espresso drivers | | --- | --- | --- | | What gets signed for the session | the **test agent**, WebDriverAgent | the **app under test** | | Why | the device will not launch an unsigned, unprovisioned app | signatures have to line up for instrumentation | | Configured with | `appium:xcodeOrgId`, `appium:xcodeSigningId`, `appium:updatedWDABundleId` | `appium:noSign`, `appium:useKeystore` and the keystore capabilities | | Provisioning profile | required on a real device | does not exist | So there is no `appium:xcodeOrgId` equivalent on Android, and no keystore equivalent on iOS. Both platforms sign something; they sign different artifacts for different reasons, and a capability set copied from one lane into the other is simply ignored. ## What sits outside this capability set - Producing and shipping a signed release of the snowplough dispatch application, including certificates and their synchronisation across a team, belongs to release tooling rather than to a session's capabilities. - WebDriverAgent as a running component, meaning how it is launched, reached and kept alive, is a separate subject. These three capabilities decide only how it is signed. - Working out why a session died while the agent was starting is its own discipline. Knowing what the signing capabilities mean is an input to that, not the whole of it. The practical summary for a real-device iOS lane: set `appium:xcodeOrgId` always, leave `appium:xcodeSigningId` alone unless you have a reason, and reach for `appium:updatedWDABundleId` the moment the profile you hold does not cover the agent's stock identifier.

  • Does an Appium iOS simulator session need appium:xcodeOrgId?
    No. A simulator does not enforce the provisioning rules a physical device does, so the agent builds and installs without a team identity. The capability starts to matter only when the session targets real hardware, which is why a suite that has only ever run on simulators meets signing for the first time on a real iPhone.
  • What signs the snowplough dispatch application itself on iOS?
    Not Appium. The XCUITest driver signs the agent; the application under test must arrive already signed for the target device, from your own build tooling. The driver installs the artifact you hand it and does not re-sign it, which is the opposite of what the Android drivers may do.

The agent is a contractor's own van: the site will not open the gate for it unless it carries your company's pass, even though the van was never yours.

saying these in an interview costs you the question

  • Says Appium signs the iOS app under test as well as the agent
  • Thinks appium:xcodeOrgId is needed for Apple simulator runs
  • Claims Android has no signing capabilities at all
  • Confuses the agent's bundle identifier with the app under test's
  • Assumes any team's profile already covers the agent's stock bundle identifier
open as a page

In Appium, what does the app capability accept, and which identity key does each platform read from it?

level: middleimportance: must knowfreq 72%

basics

~20 s

The app capability takes a local path or http URL to one build artifact: an APK for Android, an IPA or .app bundle for iOS. Each driver reads the app identity from it - the Android package name, the iOS bundle id.

open as a page

In Appium on Android, what do the appium:noSign and appium:useKeystore capabilities control?

level: middleimportance: must knowfreq 47%

basics

~20 s

Both act on the Android app under test, not on a test agent. By default the drivers can re-sign the build with appium-adb's bundled certificate; appium:noSign skips that step, and appium:useKeystore keeps it but signs with your own keystore instead.

open as a page

An Appium session drives yesterday's build though the app capability names a new artifact. Why?

level: seniorimportance: must knowfreq 55%

basics

~20 s

Because the install is conditional. Both the Android drivers and the XCUITest driver compare the artifact against the build already installed under the same identity and skip the install when they judge it unnecessary. appium:enforceAppInstall forces it.

open as a page

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%

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.

open as a page

In Appium on Android, why does letting the drivers re-sign the build change what a run proves?

level: seniorimportance: should knowfreq 42%

basics

~20 s

The APK the session installs is no longer the one your pipeline produced: the Android drivers re-sign it with appium-adb's bundled certificate when a certificate check fails, so anything keyed to the original signature behaves differently. appium:noSign installs it untouched.

open as a page

For an Appium suite, when should capabilities ship the artifact rather than name an installed build?

level: principalimportance: should knowfreq 38%

basics

~20 s

Ship the artifact with app when the run must prove which build it exercised. Name the installed build with appium:appPackage on Android or appium:bundleId on iOS when session start time dominates and something else provisions the device.

open as a page

In an Appium real-device iOS lane, how do you weigh the upkeep of agent signing?

level: principalimportance: should knowfreq 36%

basics

~20 s

Treat it as standing cost, not setup. Every real Apple device the lane touches must sit under a team profile, the agent is signed on a macOS host with Xcode, and identities expire. Android carries no equivalent gate.

open as a page