In an Appium dental-recall run, two workers on one host drive the same phone — how do you pin each?
answer
- the request never named a target
- pin with a key that selects
- udid or avd per Android worker
- model and runtime per simulator worker
- record the key that actually selected
basics
~10 sGive every worker a capability map that names its own target with a key that platform actually selects on: appium:udid or appium:avd on Android, appium:udid or appium:deviceName with appium:platformVersion on Apple platforms.
solid answer
~40 sTwo workers landing on one phone means neither request named a device with a key that selects. The fix is per-worker capability maps, and the key differs by platform: on Android, `appium:udid` for an attached handset or `appium:avd` for a named emulator; on Apple platforms, `appium:udid` for a real device and `appium:deviceName` with `appium:platformVersion` for a simulator. Giving each worker a different `appium:deviceName` will not do it on Android — the drivers accept the key and select on something else, so the maps only look different. Then make the pin auditable: record the key that actually selected, not the friendliest one, so a failure report can name the machine. Unique per-session ports are a separate requirement and a separate subject.
code
json · 12 lines{
"worker1": {
"platformName": "Android",
"appium:automationName": "UiAutomator2",
"appium:udid": "<serial adb reports for rack handset 1>"
},
"worker2": {
"platformName": "Android",
"appium:automationName": "UiAutomator2",
"appium:udid": "<serial adb reports for rack handset 2>"
}
}go deeper
Be ready to name the key that pins a target on each platform: appium:udid or appium:avd on Android, appium:udid or appium:deviceName with appium:platformVersion on Apple platforms. One selecting key per worker, unique values.
Explain why differing appium:deviceName values do not separate two Android workers, and why an Apple simulator description stops being a pin as soon as two identical model-and-runtime simulators exist.
Show the whole loop: read the symptom, pin each worker with a selecting key, and make the pin auditable so a failing run can name its machine rather than quoting a key the driver never read.
Own what unpinned runs cost as evidence — device-specific defects that cannot be reproduced, and hardware claims nobody can substantiate — and set the standard that every concurrent worker names and records its own target.
Two workers driving the same handset is not a race condition to tune away. It is a request that never named a target. When a capability map carries no key the platform selects on, two identical maps get the same answer twice, and the run's results belong to a machine nobody chose. ## Read the symptom precisely Before changing anything, separate three situations that look alike from the outside: - Both workers reached the same device because neither map named one. - Both workers reached the same device because both maps named the same one. - The workers reached different devices and interfered through something else the host shares. The first two are this problem and are fixed with selection keys. The third is a different subject — what a parallel worker must hold uniquely beyond its target, including the per-session ports, is owned elsewhere and is not solved by naming a device. ## Pin the Android workers On Android the selecting keys are `appium:udid` and `appium:avd`: - Real handsets in a rack: each worker's map carries its own `appium:udid`, holding the serial adb reports for that handset. - Emulators on a build machine: each worker's map carries its own `appium:avd`, naming a distinct AVD. What will not work is giving each worker a different `appium:deviceName`. The Android drivers accept the key and select on something else, so two maps that differ only there are, for selection purposes, the same map. This is the most common wrong fix, and it is convincing precisely because the maps now look different and the reports now print different names. ## Pin the Apple workers On Apple platforms the keys change with the kind of target: - A real device: `appium:udid` per worker, holding that device's UDID. - A simulator: `appium:deviceName` for the model and `appium:platformVersion` for the runtime, per worker. ## The limit of the simulator pair `appium:deviceName` with `appium:platformVersion` is a description, not an identity. Two simulators of the same model on the same runtime are not separable by it, so a fleet containing identical twins cannot pin them apart with that pair alone. Design around the limit instead of fighting it: give each dental-recall worker a distinct model, or a distinct runtime, so the description is unambiguous for every worker running at the same time. ## Make the pin auditable A pin you cannot prove is a pin you will re-argue during the next incident. For the dental-recall suite that means each run records the key that actually selected, with its value: 1. Android lanes record the `appium:udid` or the `appium:avd` that was sent. 2. Apple real-device lanes record the `appium:udid`. 3. Apple simulator lanes record both `appium:deviceName` and `appium:platformVersion`, because either alone is incomplete. 4. No lane treats `appium:deviceName` on Android as evidence of anything, because it selected nothing there. The failure this prevents is a specific one. A recall-reminder screen fails on one handset in the rack; the report names a device; the team spends an afternoon on the wrong hardware because the report was quoting a key the driver never read. ## A checklist for any lane - Does every worker's map carry a key that selects on that platform? - Is that key's value unique across the workers that run at the same time? - If the value is a description rather than an identity, is the description unique in the fleet? - Does the run record that key and value, rather than the friendliest key in the map? - When a device leaves the fleet, does something fail loudly, or does a stale value quietly land the worker elsewhere? ## What it costs to leave unpinned An unpinned suite is not merely at risk of collisions. It loses the ability to say what its own results are about. Device-specific defects cannot be reproduced, because the device is unknown. Flake cannot be attributed, because the population that produced it changes from run to run. And a green suite is weaker evidence than it appears, since any claim about which hardware was exercised rests on which machines actually ran — which, without a selecting key in every map, nobody can state. The discipline is small and it holds everywhere: one selecting key per worker, unique per concurrent run, recorded with the result.
- Two Apple simulators of the same model and the same runtime are installed. What does the naming pair buy you?Nothing that separates them. `appium:deviceName` with `appium:platformVersion` describes a model and a runtime, and two targets sharing both are indistinguishable by that description. Design around it by giving each worker a distinct model or a distinct runtime, rather than expecting the pair to separate identical twins.
- How do you prove after the fact which machine a failing dental-recall run used?Record the selecting key and its value with the run, not the human-readable one. On Android that is `appium:udid` or `appium:avd`; on an Apple simulator it is `appium:deviceName` with `appium:platformVersion`. A report printing `appium:deviceName` for an Android run is quoting the request, not the machine, because that key selected nothing there.
saying these in an interview costs you the question
- Fixes it by giving each worker a different appium:deviceName on Android
- Assumes two workers cannot collide once the driver is named
- Reads the friendly device name in a report as the machine that ran
- Names an Apple simulator by model only and expects two distinct targets
- Thinks naming the target is all a parallel worker must hold uniquely