In Appium, which attribute tells you a switch is on for Android, and which for iOS?
answer
- same request, different name segment
- Android names the state directly
- iOS packs the state into a general field
- a digit string, not a boolean word
basics
~20 sAndroid's UiAutomator2 driver exposes the switch position as its own attribute, checked, reading back as true or false. iOS's XCUITest driver folds the position into the general value attribute, where an on switch reads back as 1.
solid answer
~40 sTake a milk-round delivery app's *skip tomorrow* toggle. Both platforms answer through the same request, `GET /session/:sessionId/element/:elementId/attribute/:name` — only the `:name` segment changes. On **Android**, through the UiAutomator2 driver, you read `checked` and get `true` or `false`. On **iOS**, through the XCUITest driver, there is no dedicated name for the toggle position; it lives in the element's general `value`, where on is `1` and off is `0`. The four names this leaf pins on each side — `checked`, `enabled`, `displayed`, `bounds` against `value`, `label`, `visible`, `hittable` — overlap in nothing, so no single name gets you the switch state on both. Treat the reply as text and compare it against the platform's expected token: a truthiness check passes for the non-empty string `false` too.
go deeper
Be ready to name the two attributes: checked on Android through the UiAutomator2 driver, value on iOS through the XCUITest driver, and say that an on switch reads back as true on one and 1 on the other.
Explain why the same request serves both platforms while the name segment does not, and why value is a general slot on iOS that holds typed text on a field and a digit on a switch.
Show where you normalise the raw reply into a boolean, and how you keep the per-platform name and on-token pair in one lookup rather than scattered platform branches across the suite.
Argue what the suite standardises on: a platform-free vocabulary at the test layer with one adapter beneath it, and what you accept in exchange when a new control type adds another token to the mapping.
## Why one widget answers to two names A milk-round delivery app puts a **skip tomorrow** switch on every customer card, and a test wants to assert that the switch is on. The mechanics of that read are identical on both platforms: once a find has produced an element identifier, the client issues `GET /session/:sessionId/element/:elementId/attribute/:name` and gets back the single value stored under `:name`. What is not identical is the `:name` you are allowed to put in it. Appium does not invent an attribute vocabulary of its own — each driver re-exports the names the platform underneath it already uses, and those two sets of names were never coordinated with each other. On **Android**, through the UiAutomator2 driver, the toggle's position has a name of its own: `checked`, which reads back as `true` or `false`. On **iOS**, through the XCUITest driver, there is no dedicated name for *is this toggle on*; the position is folded into the element's general-purpose `value`, and a switch that is on reports `1` while one that is off reports `0`. ## The two vocabularies side by side | What the test wants to know | Android — UiAutomator2 driver | iOS — XCUITest driver | | --- | --- | --- | | Is the switch on? | `checked` (`true` / `false`) | `value` (`1` / `0`) | | Does it accept input? | `enabled` | — | | Is it drawn on screen? | `displayed` | `visible` | | Would a touch reach it? | — | `hittable` | | Where is it on screen? | `bounds` | — | | What text describes it? | `content-desc` | `label` | The dashes are the point. The four names pinned on each side overlap in nothing at all, so there is no attribute name you can send to both drivers and get the switch position back from. Read the table as a warning rather than as a translation dictionary. `checked` and `value` are **not aliases**. `value` is the generic slot XCUITest fills with whatever a control's current setting happens to be: typed text in a text field, a number on a slider, a digit on a switch. `checked` is narrow and means exactly one thing. Treating the two as two spellings of one concept is how a suite ends up asserting a text field's contents against the string `1`. ## The reply is JSON, not a language boolean - The value crosses the wire as **JSON**, most often as text — `true` on Android, `1` on iOS. Nothing about the endpoint promises your client hands you a native boolean. - A truthiness test on the raw return is therefore unsafe: the string `false` is non-empty, and a non-empty string is truthy in Python, JavaScript, Ruby and Groovy alike. - Compare against the platform's expected token instead — `checked` equal to `true` on Android, `value` equal to `1` on iOS — after trimming whitespace and folding case. - A name the element does not carry comes back empty rather than as `false`, so *absent* and *present and off* have to be told apart deliberately. - Read one name per request: the `:name` segment takes a single attribute, so three facts about one element cost three round trips. ## Doing the mapping once, in one place 1. State the fact the test asserts in platform-free language: *the skip-tomorrow switch is on*. 2. Map that fact to a pair per platform — an attribute name plus the token that means **on**: `checked`/`true` for the UiAutomator2 driver, `value`/`1` for the XCUITest driver. 3. Normalise at the edge, immediately after the read, so a boolean and not a string travels into the assertion. 4. Keep both pairs in one lookup. Scattering `if platformName == "Android"` through the tests spreads a two-line fact across a suite. ## What ignoring this costs - An Android assertion ported to iOS unchanged reads a name the element does not carry, gets an empty result, and reports the switch as **off** — a green-to-red flip with no defect behind it, or worse, a false pass. - A test that reads `value` on both platforms gets the switch position on iOS and something quite different on Android, because the two vocabularies do not agree on what `value` even holds. - A suite that never normalises accumulates comparisons against `true`, `false`, `1` and `0` as raw strings, and every new control adds another token to remember. The durable habit is small: never write an attribute name in a test without knowing which driver will answer it, and never let a raw attribute string past the first line that reads it.
- Why is a truthiness check on the returned attribute value unsafe on either platform?The value arrives as JSON, usually as text. `false` on Android and `0` on iOS are both non-empty strings, and a non-empty string is truthy in Python, JavaScript and Ruby, so the check reports every switch as on. Compare against the platform's expected token instead, after trimming and folding case.
- How do you tell an absent attribute from one that is present and off?A name the element does not carry comes back empty rather than as a false-ish token, so an empty result means *this driver has no such attribute here*, not *the switch is off*. Assert on the token you expect — `true` on Android, `1` on iOS — and treat empty as a locator or platform-mapping bug worth failing loudly on.
Two dairies record the same standing order: one ticks a column headed skip, the other writes a 1 in a column headed quantity. The fact is identical; the vocabulary is not.
saying these in an interview costs you the question
- Says checked works on iOS because the widget looks the same
- Treats the returned attribute value as a native boolean
- Assumes a non-empty return means the switch is on
- Calls checked and value two spellings of one attribute
- Thinks the endpoint differs per platform rather than the name