skip to content

Link Degradation

Degrading the link from inside the session. The two platforms share no machinery here: one toggles radios and throttles an emulator, the other borrows an Apple facility that needs real hardware.

on this pageshow

explore

questions

3

In Appium, which command switches Wi-Fi off on Android, and what does iOS offer instead?

level: juniorimportance: should knowfreq 52%

answer

  1. two platforms, no shared command
  2. Android flips radios in session
  3. iOS borrows an Apple condition profile
  4. setConnectivity, never setNetworkSpeed
  5. list the inducers before enabling one

basics

~20 s

On Android, the execute method mobile: setConnectivity toggles wifi, mobile data and airplane mode. iOS has no equivalent radio switch: the XCUITest driver enables one of Apple's network condition profiles instead, and only on a real device.

solid answer

~40 s

Android and Apple share no machinery here. On **Android**, `mobile: setConnectivity` — declared by `appium-android-driver`, so both the UiAutomator2 and the Espresso driver have it — takes booleans for wifi, mobile data and airplane mode, and `mobile: getConnectivity` reads the state back. Appium 3's migration guide points the older `toggle_wifi`, `toggle_data` and `toggle_airplane_mode` device routes at it. On **iOS** there is no radio toggle at all. The XCUITest driver exposes `mobile: enableConditionInducer`, `mobile: disableConditionInducer` and `mobile: listConditionInducers`, which switch on one of the operating system's own condition profiles — a degraded link rather than a dead radio — and that facility is **real-device only**. Discover the condition and profile identifiers at runtime with `mobile: listConditionInducers` rather than hardcoding them.

code

java · 12 lines
java
// parking-permit renewal run: degrade the link, observe, restore

// Android (appium-android-driver): drop mobile data, keep wifi, then read the radios back
driver.executeScript("mobile: setConnectivity", Map.of("wifi", true, "data", false));
Object radios = driver.executeScript("mobile: getConnectivity");

// Apple real device (XCUITest driver): discover what the OS can induce, then enable a pair from it
Object inducers = driver.executeScript("mobile: listConditionInducers");

// teardown, one call per platform
driver.executeScript("mobile: setConnectivity", Map.of("wifi", true, "data", true));
driver.executeScript("mobile: disableConditionInducer");

go deeper

for a junior

Be ready to name the Android command, mobile: setConnectivity, and to say plainly that iOS has no radio toggle and uses Apple's condition inducers instead, on real devices only.

for a middle

Explain where each command lives: setConnectivity in appium-android-driver, which UiAutomator2 and Espresso both extend, and the condition inducers in the XCUITest driver, which only switches on a facility the operating system provides.

for a senior

Show how a suite branches by platform at the environment-control layer, and how it puts connectivity back and disables an inducer even when the test body throws part way through.

for a principal

Own the consequence for the device pool: the Android throttle wants an emulator and the Apple one wants real hardware, so a network-condition suite cannot be planned as though one target type served both.

## Two platforms, no shared machinery Appium lets a running session change the network the device sees, but **Android and Apple share nothing here** — not a command name, not a mechanism, not even the same kind of effect. On Android a driver execute method flips the device's radios. On Apple the XCUITest driver switches on a *condition profile* that the operating system itself provides. Any sentence that describes the Appium way to take the network away is describing one of those two and silently ignoring the other, and on this subject that is exactly what an interviewer is listening for. ## Android: mobile: setConnectivity The command is `mobile: setConnectivity`, and it is declared by **`appium-android-driver`**, the base driver that both the UiAutomator2 driver and the Espresso driver extend. That matters twice over: the command is available in an Android session whichever of those two `appium:automationName` selected, and hunting for it in the UiAutomator2 repository will not find it, because that repository's own execute-method map carries only gesture and window commands. Like every `mobile:` method it travels as `POST /session/:sessionId/execute/sync` with the script name and one parameter map; a language client such as java-client wraps that in `executeScript`. The map carries the three radios Android exposes to the driver: - **wifi** — the Wi-Fi radio on or off - **mobile data** — the cellular data connection on or off - **airplane mode** — the umbrella switch that takes the others with it You send only the keys you mean to change. `mobile: getConnectivity` is the read-back twin, and it is worth calling: it reports the state the device actually settled on rather than the state you asked for. These execute methods are also the current spelling of something older. Appium 3's migration guide points the previous `toggle_wifi`, `toggle_data` and `toggle_airplane_mode` device routes at `mobile: setConnectivity`, so a helper in an inherited suite that still posts to those paths has an obvious replacement. ## Apple: a facility the driver borrows The XCUITest driver's answer is a trio: `mobile: enableConditionInducer`, `mobile: disableConditionInducer` and `mobile: listConditionInducers`. The important word is *inducer*. Appium is not simulating a bad link; the operating system ships a set of condition profiles, and the driver's whole job is to switch one on by naming a condition and one of its profiles. Because those identifiers belong to the platform rather than to Appium, the honest way to use them is to call `mobile: listConditionInducers` first and take the pair out of the response. Three properties define the feature: - It is **real-device only** — a Simulator has no condition inducer to switch on. - It **degrades**; it does not disconnect a radio, and there is no Wi-Fi switch anywhere in this API. - It has an **explicit undo**, `mobile: disableConditionInducer`, which a run should call rather than hope the session teardown covers it. There is a documentation trap here too, and it is the kind that survives a careless copy-paste: the driver's own reference prose prints `mobile: availableConditionInducer`, a name that appears in no method map in the driver. The listing command is `mobile: listConditionInducers`. ## Side by side | Concern | Android drivers | XCUITest driver | |---|---|---| | set it | `mobile: setConnectivity` | `mobile: enableConditionInducer` | | inspect it | `mobile: getConnectivity` | `mobile: listConditionInducers` | | effect | radios on or off | one operating-system condition profile | | targets | emulator or handset | real devices only | | undo | write the flags back | `mobile: disableConditionInducer` | ## Putting it in a run Take a parking-permit renewal app that must show a queued-renewal notice when the handset has no data. On Android the step is direct: switch data off with `mobile: setConnectivity`, drive the renewal, assert the notice, switch data back on. On Apple the same step cannot exist in that shape — on a real iPhone you enable a network condition profile and the request degrades instead of vanishing, and on a Simulator the driver offers you nothing at all. The practical consequence is that a cross-platform suite has **two implementations behind one intent**, not one shared call. Suites that pretend otherwise grow a helper named something like setOffline() that works on Android, throws on Apple hardware, and quietly does nothing on a Simulator. ## What a good answer sounds like 1. Name the Android command, `mobile: setConnectivity`, and the package that declares it. 2. Name the Apple trio and say that it enables an operating-system condition profile, on real devices only. 3. State the asymmetry out loud rather than describing one platform and stopping. If a follow-up asks about throttling rather than switching, that is `mobile: networkSpeed` — a different Android command with its own restriction, and not a synonym for `mobile: setConnectivity`.

  • Which package declares mobile: setConnectivity, and why does that matter?
    It is declared by `appium-android-driver`, the base driver that the UiAutomator2 and Espresso drivers both extend — not by the UiAutomator2 repository, whose own execute-method map carries only gesture and window commands. It matters because the command is there whatever `appium:automationName` picked, and because looking in the wrong repository makes it appear not to exist.
  • How do you find the condition and profile identifiers an iPhone will accept?
    Call `mobile: listConditionInducers` on the XCUITest session and take the identifiers out of the response, then pass the pair to `mobile: enableConditionInducer`. Do not hardcode names from documentation: the driver's own docs print `mobile: availableConditionInducer`, which exists in no method map, and the profiles belong to the operating system rather than to Appium.

saying these in an interview costs you the question

  • Says one Appium command degrades the link on both platforms
  • Calls it mobile: setNetworkSpeed, a name no driver declares
  • Thinks mobile: setConnectivity works in an iOS session
  • Expects condition inducers to work on an iOS Simulator
  • Hardcodes a condition profile name instead of listing them first
open as a page

In Appium, why does mobile: networkSpeed need an Android emulator while iOS condition inducers need a real device?

level: middleimportance: should knowfreq 44%

basics

~20 s

Each command drives a facility only one kind of target has: mobile: networkSpeed configures the Android emulator's simulated modem, which a real handset lacks, while Apple's condition inducers ship on real devices and not on a Simulator.

open as a page