skip to content

In an Appium session with appium:autoLaunch false, how does the app get started on Android and Apple platforms?

level: seniorimportance: should knowfreq 41%

answer

  1. the driver stops short of starting
  2. session created, app prepared, nothing shown
  3. your first command is the start
  4. activate or start a component on Android
  5. launchApp on Apple platforms

basics

~10 s

The session is created and the app prepared on the device, but nothing is brought to the foreground. The test starts it: mobile: activateApp or mobile: startActivity on Android, mobile: launchApp on Apple platforms.

solid answer

~40 s

`appium:autoLaunch` is one of the core base capabilities, so it carries the `appium:` prefix like every other non-standard name. Setting it to `false` says *create the session and get the app onto the device, but do not start it for me*. The first command a test sends is then a lifecycle command: on Android `mobile: activateApp` for the app as a whole or `mobile: startActivity` for one named component; on Apple platforms `mobile: launchApp` for a cold start, or `mobile: activateApp` if a resume will do. It is the right switch when something must be arranged before the app ever runs, or when the very first frame is what the case is about. It is not a reset switch, and it does not skip preparing the app on the device.

code

java · 12 lines
java
MutableCapabilities caps = new MutableCapabilities();
caps.setCapability("platformName", "Android");
caps.setCapability("appium:automationName", "UiAutomator2");
caps.setCapability("appium:app", "/builds/bustracker.apk");
caps.setCapability("appium:autoLaunch", false);

AndroidDriver driver = new AndroidDriver(new URL("http://127.0.0.1:4723"), caps);
String appId = "com.schooldistrict.bustracker";

driver.executeScript("mobile: activateApp", Map.of("appId", appId));
Object state = driver.executeScript("mobile: queryAppState", Map.of("appId", appId));
System.out.println(state);

go deeper

for a junior

Remember that this capability decides whether the driver starts the app for you, and that with it off your test must send a start command before it can find anything.

for a middle

Explain the split it creates: session creation and app preparation still happen, only the start is withheld, and the start command differs between the Android drivers and the XCUITest driver.

for a senior

Show when you would actually turn it off — first-frame cases, conditions arranged before startup, a measured launch — and how you verify the manual start rather than assuming it worked.

for a principal

Own the boundary between this capability and the reset capabilities, and set where the manual start lives so every lane in the suite begins from the same verified condition.

## What the capability does `appium:autoLaunch` is one of the small set of base capabilities the Appium core itself declares, alongside names such as `app`, `noReset` and `newCommandTimeout`. Like all of them it is not a W3C standard capability, so it must be written with the `appium:` prefix in the session request. Its default behaviour is the one most people never think about: the driver prepares the app on the device and starts it, so by the time the session request returns, the app under test is on screen and the first find works. Setting the capability to `false` splits that into two steps. The session is created, the app is prepared on the device, and then the driver stops — nothing is brought to the foreground, and the first command the test sends decides what happens next. ## Starting it yourself, per platform The start becomes an ordinary lifecycle command, and the choice is the platform-divergent part: - **Android** — `mobile: activateApp` with the package name starts the app at its normal entry point, or `mobile: startActivity` starts one named component when the case needs to land on a specific screen. - **Apple platforms** — `mobile: launchApp` starts the app under the XCUITest driver's control, which is the cold start; `mobile: activateApp` is the choice when resuming whatever is already there is acceptable. This is the same asymmetry the lifecycle surface has everywhere: the Android drivers can start a component, the XCUITest driver starts the app. Turning the automatic launch off changes nothing about that; it only moves the decision out of the capability set and into the test body. ## Why a suite would want this For a school bus tracking app, there are a handful of honest reasons to take the launch into your own hands: 1. **The first frame is the subject.** A case about what the driver sees when the app opens at the start of a shift cannot afford to have the app already running before the first observation. 2. **Something must be arranged first.** Device conditions, a log capture, or a state the app reads at startup are all easier to set while the app is definitely not running. 3. **The start itself is being measured.** If the case cares how the app comes up, the launch has to be an observable step rather than something that happened before the session handle existed. 4. **Another app goes first.** A flow that begins outside the app under test wants to control the moment the tracker comes forward. 5. **The Android case wants a component start.** Letting the driver launch the default entry point and then starting a component means two starts; turning the automatic one off means one. ## What it does not change - **It is not a reset switch.** Whether stored data survives between sessions is decided by the reset capabilities, which are a separate subject with their own rules on each platform. Turning off the automatic launch changes *when* the app starts, not *what state* it starts in. - **It does not skip preparation.** The app is still put on the device according to the session's other capabilities; only the start is withheld. - **It does not change teardown.** The session ends the way any session ends, and an app you started by hand is still an app the next session may find running. - **It does not make the first find safe.** Nothing is in the foreground until you put it there, so a suite that flips this capability without adding a start step fails on its first element lookup — usually with an error that says nothing about the real cause. ## Getting it right in practice Put the manual start where the automatic one would have been: a fixture or setup step that every case in the lane shares, not scattered through individual tests. Confirm it with `mobile: queryAppState` rather than assuming — the state query is answered on both platforms, and it turns *the app never started* into a clear failure at the start step instead of a confusing element timeout later. And write the platform branch once. The Android lane picks between activating the app and starting a component, the Apple lane picks between a cold start and a resume, and both lanes end in the same verified condition: the school bus tracking app is in the foreground and the case can begin.

  • What is the first symptom of forgetting the start step after setting appium:autoLaunch to false?
    The first find in the case fails, and the error talks about an element rather than about a missing app. Reading `mobile: queryAppState` at the top of the setup turns that into an obvious failure: the app sits at the not-running rung because nothing ever started it.
  • Is appium:autoLaunch a way to keep the app's stored data between sessions?
    No. It decides only whether the driver starts the app for you at session creation. What survives between sessions is governed by the reset capabilities, which behave differently on Android and on Apple platforms. Conflating the two produces a suite that is surprised by state it never asked to keep.

saying these in an interview costs you the question

  • Thinks autoLaunch false also skips putting the app on the device
  • Confuses appium:autoLaunch with the reset capabilities
  • Expects the first find to start the app automatically
  • Writes autoLaunch without the appium vendor prefix
  • Uses mobile: launchApp in the Android lane after disabling autoLaunch