skip to content

Your Appium ferry timetable suite starts every iOS real-device session already signed in, though appium:noReset is false. Why?

level: seniorimportance: must knowfreq 52%

answer

  1. the flag is permission, not an action
  2. no artifact, no reinstall
  3. iOS clean-up is install-shaped
  4. simulator-only clear on Apple hardware

basics

~20 s

Because appium:noReset false only asks the XCUITest driver for its normal clean-up, and on a real device that clean-up is a reinstall. A session that names an already-installed bundle with no build to install clears nothing.

solid answer

~40 s

`appium:noReset: false` is not an instruction to clear data; it is permission for the driver to do its usual between-session clean-up, and the XCUITest driver's only real lever on a device is install and uninstall. If the session identifies the app by bundle id and supplies no artifact, there is nothing to reinstall, so the container — including the stored token that keeps you signed in — survives untouched. `mobile: clearApp` would empty that container, but on Apple platforms it is simulator-only and throws on hardware. Three honest fixes: ship the build with the session so the reinstall actually happens; set `appium:fullReset` and accept the per-session cost; or stop relying on the capability altogether and have the suite sign out or reset through the app, then assert the signed-out state before the case begins.

go deeper

for a junior

Take away one fact: a reset capability set to false is permission for the driver to clean up, not a promise that data was deleted. Check what actually happened before trusting it.

for a middle

Explain why the Apple clean-up needs a build to install while the Android one does not, and why that difference makes the same capability value mean two different things.

for a senior

Show a diagnosis path rather than a guess: a marker value across two sessions, the server log at session start, and a simulator-versus-hardware comparison to confirm the divergence.

for a principal

Decide where the isolation contract lives for the whole fleet, and make it observable — a capability nobody has verified on hardware is a promise the organisation has been believing for free.

## What the capability actually promises The first correction to make is to the mental model, not the config. `appium:noReset: false` does not say *clear this app's data*. It says *you may do your normal between-session clean-up*, and it is each driver that decides what that clean-up is. On Android the drivers clear the app's data in place through the package manager, and the promise is unconditional: any installed package can be emptied. On Apple platforms the XCUITest driver has no in-place clear it can use on a device, so its clean-up is **install-shaped** — the app is reinstalled, and the old container goes with the old copy. An install-shaped clean-up has a precondition that a data clear does not: **there has to be something to install**. A session that identifies the ferry timetable app by an already-installed bundle and supplies no artifact gives the driver nothing to do. No error is raised, because nothing went wrong; the driver simply had no clean-up to perform. Your suite then opens the app on the previous run's data, including whatever kept it signed in. ## Why the Apple lane is the one that breaks The simulator lane usually hides this, which is why the bug reaches hardware. On a simulator a suite often does install the build every session, and `mobile: clearApp` is available as a fallback that empties the app's data container. On a real device neither holds: - `mobile: clearApp` is **simulator-only**, so calling it on hardware fails the case rather than cleaning it. - Without an artifact, no reinstall happens, so the default reset is a no-op. - Nothing in the run turns red, so the suite has been running dirty for as long as anyone cares to look back. Meanwhile the Android lane is genuinely clean on the same configuration, which is exactly what makes the report so convincing and so misleading. A green cross-platform run does not mean both lanes were isolated. ## Reading the run instead of guessing Prove the mechanism rather than arguing about it: 1. **Write a marker, then look for it.** In one session store an obvious value in the app; start a second session with the same capabilities and read it back. If it is there, nothing was cleared. 2. **Read the server log around session start.** Look for whether the driver installed anything at all. A session that never installed cannot have reset anything. 3. **Check what the capabilities actually identify.** A session pointed at an installed bundle with no build is the classic shape of this defect. 4. **Run the same case on a simulator.** If it is clean there and dirty on hardware, you have confirmed the divergence rather than a bug in the app. ## The three fixes and what each costs | fix | what it buys | what it costs | |---|---|---| | ship the build with every session | the reinstall really happens, so the container is genuinely fresh | an install per session on real hardware, plus getting the artifact to the run | | set `appium:fullReset` | the app is removed before the session, the strongest guarantee there is | the same install cost plus the removal, on every single session | | let the suite reset state itself | works identically on both platforms and on hardware | you must build and maintain a sign-out or reset path, and prove it ran | The third is the one senior suites usually land on, because it is the only option whose behaviour does not change when the lane changes. It also has a trap of its own: swapping a silent driver assumption for a silent suite assumption gains nothing. Whatever the reset path is, the case must **assert** the state it expects before it starts, so a dirty start fails at the first step with an obvious message instead of surfacing three screens later as a flake. ## What this should change about the Android result The useful takeaway is not *iOS is broken*. It is that the reset capabilities express intent while each platform supplies a mechanism, so a value that means *cleared* on one lane can mean *untouched* on another. Two habits follow: - Never generalise a clean simulator lane to a real-device lane; the available mechanisms are not the same. - Never treat a capability as a guarantee you have not observed at least once on the hardware you actually run. And resist two tempting non-fixes. Raising a timeout does nothing, because nothing is slow — nothing is happening at all. Blaming the app for caching too aggressively is equally wide of the mark: the app is behaving correctly for an install that was never replaced.

  • How would you prove the app was never cleared rather than guessing at it?
    Run the same session twice with a marker: write an obvious value in the first run and read it at the start of the second. Then read the server log for what the driver did at session start — either it installed the app or it did not. A session that never installed anything cannot have reset anything.
  • The same suite is clean on the iOS simulator lane. What explains the difference?
    A simulator lane usually installs the build every session, and `mobile: clearApp` is available there as a fallback, so the container really is emptied. On hardware neither holds: the clear command is simulator-only, and without an artifact no reinstall happens. Never generalise a clean simulator result to a real-device lane.

saying these in an interview costs you the question

  • Assumes appium:noReset false guarantees a clean iOS device
  • Blames the app for caching instead of checking the reset
  • Suggests mobile: clearApp on an Apple real device
  • Concludes the server silently ignored the capability
  • Generalises a clean simulator lane to real hardware
  • Raises timeouts hoping the state clears itself