skip to content

On an iOS Simulator, why does Appium's mobile: clearApp leave the museum audio-guide app signed in?

level: seniorimportance: must knowfreq 47%

answer

  1. the container is not everything
  2. one store sits outside the sandbox
  3. credentials survive a container delete
  4. a second Simulator-only command exists

basics

~10 s

Because the sign-in token lives in the iOS keychain, which sits outside the app data container that mobile: clearApp deletes. XCUITest ships mobile: clearKeychains for that store, and it is Simulator-only as well.

solid answer

~40 s

The XCUITest driver's `mobile: clearApp` deletes the app's **data container** — the sandbox directory holding its databases, preference files and cached media. The **keychain is a separate store**, so a membership token the museum audio-guide app wrote there is untouched, and the app relaunches already signed in. The companion is XCUITest's `mobile: clearKeychains`, which empties the Simulator's keychain; like `mobile: clearApp` on that platform it is **Simulator-only**. Pair the two whenever a case needs a genuinely signed-out start, and do the keychain wipe before you bring the app back. Android rarely shows the same gap: a package-data clear takes the package's whole private data directory in one call, so a token the app kept in its own preferences or database goes with everything else.

go deeper

for a junior

Know that emptying an iOS app's stored data does not sign a user out by itself, and that Appium has a separate command aimed at the keychain.

for a middle

Be ready to say what an XCUITest data-container delete covers, why the keychain sits outside it, and which command clears that store.

for a senior

Explain how you sequence the two calls inside a per-case hook, and why the keychain wipe is Simulator-wide rather than scoped to one app.

for a principal

Own where credential state should live for testability, and decide whether a Simulator-wide keychain wipe is acceptable on shared infrastructure.

## The symptom A case for the **museum audio-guide app** is supposed to start at the membership sign-in screen. The suite calls `mobile: clearApp` on the Simulator, the app relaunches, and it opens on the visitor's saved tour list with the member badge still in the corner. Nothing failed and the driver returned success. The wipe simply did not reach the thing that keeps the visitor signed in. ## What a container delete actually reaches On Apple platforms `mobile: clearApp` is implemented by the XCUITest driver as a delete of the app's **data container** — the sandboxed directory tree the app writes into. That is a real and useful blast radius: - Databases the app created for downloaded tours and exhibit bookmarks. - Preference files, including the chosen language and the resume position in a tour. - Cached audio and images the app fetched for the Renaissance-wing walkthrough. - Temporary files written while a tour download was in flight. What it is not is everything the app can read on the next launch. The **keychain** is a system-owned store outside that container: the app addresses it, but it does not live in the app's directory tree. Deleting the container therefore leaves the keychain exactly as it was, and a token written there is still present when the app comes back. That is not a defect in the command; it is the boundary the command was defined against. ## The companion command XCUITest ships `mobile: clearKeychains` for the other half. It empties the Simulator's keychain, and like `mobile: clearApp` on that platform it is **Simulator-only** — the same restriction, for the same underlying reason. The two are meant to be used together when a case needs a truly signed-out start: 1. Stop interacting with the app and let it leave the foreground. 2. Call `mobile: clearApp` with the bundle id to delete the container. 3. Call `mobile: clearKeychains` to empty the keychain. 4. Bring the app back to the foreground, then assert the sign-in screen. Sequence the keychain wipe before the relaunch. An app that starts, reads a token and writes fresh state of its own has already re-created the thing you were about to assert against. Be aware of the second command's blast radius: it clears the **Simulator's** keychain, not just this app's slice of it. On a Simulator dedicated to one suite that is exactly what you want. On one shared with other apps or other work it is a bigger hammer than the container delete, and that is worth knowing before wiring it into a per-case hook. ## Why the asymmetry is an Apple-side problem | | Android drivers | XCUITest driver | |---|---|---| | What one call wipes | the package's whole private data directory | the app's data container only | | Credential store | inside that directory when the app used its own storage | separate keychain, survives the wipe | | Second command needed | usually none | `mobile: clearKeychains` | | Availability | emulator and real device | Simulator only, for both commands | On Android a package-data clear takes the private data directory as a unit, so a token the audio-guide app stored in its own preferences or database is gone with the rest. The extra step is usually unnecessary there, which is precisely why an engineer who learned the pattern on Android is the one most likely to be caught out on the Apple side. ## Building it into the case - Assert the signed-out state rather than assuming it. A case that opens by tapping through onboarding will pass loudly the first time and diverge quietly later. - Keep both calls in one helper so nobody adds the container wipe on its own. - Remember that neither command is available to you on an Apple real device; a suite that depends on this pairing is a Simulator suite by construction. - Do not reach for the pairing to fix state that is not on the device at all. If the museum's backend still holds an active membership session, no device-side wipe changes that, and arranging server-side records is a different subject. The one-line version to carry into an interview: on the Apple side a full wipe is two commands rather than one, because the keychain is not part of the data container — and both of those commands only run on a Simulator.

  • Does mobile: clearKeychains clear only the app under test?
    No. It empties the Simulator's keychain rather than one app's slice of it. On a Simulator dedicated to a single suite that is fine; on a shared one it is a wider blast radius than the container delete, so decide deliberately before putting it in a per-case hook.
  • Why does the same trap rarely appear on Android?
    Because the Android drivers' `mobile: clearApp` performs a package-data clear that removes the package's whole private data directory in one call. A token the app kept in its own preferences or database goes with everything else, so a second command is usually unnecessary there.

Emptying the desk drawers in a rented office is not the same as emptying the locked safe out in the corridor. The audio-guide app's credential is in the safe, and it is still there when the drawers are bare.

saying these in an interview costs you the question

  • Assumes clearing app data also clears the iOS keychain
  • Thinks mobile: clearKeychains works on an Apple real device
  • Believes the Android and iOS wipes have the same blast radius
  • Claims the app must be uninstalled to sign a user out
  • Treats a live server-side session as device state