skip to content

In Appium's Android Espresso driver, what do `-android datamatcher`, `-android viewmatcher` and `-android viewtag` each address?

level: juniorimportance: should knowfreq 48%

answer

  1. Espresso driver only, Android only
  2. two take matcher JSON, one takes a tag
  3. onView for rendered, onData for data
  4. datamatcher needs an AdapterView
  5. declared array is not the effective list

basics

~20 s

All three are Android strategies of Appium's Espresso driver. The datamatcher one builds a matcher for onData over an AdapterView's data; the viewmatcher one builds a matcher for onView over rendered views; the viewtag one matches a view's tag.

solid answer

~50 s

They are three Android-only strategies that only Appium's Espresso driver accepts — an Android UiAutomator2 session rejects all three. `-android viewmatcher` takes a JSON matcher description, builds the matcher on the device and passes it to Espresso's `onView`, so it addresses views already in the hierarchy. `-android datamatcher` takes the same JSON shape but passes the matcher to `onData`, which selects from the data behind an `AdapterView` — that is the one that reaches a hedgerow-survey species row the app has never inflated. `-android viewtag` is the simple one: it matches a view by the tag the app set on it, and the on-device server also accepts `tag name` as an alternate spelling. All three are resolved by the Espresso server running inside the Android app, not by the Appium host, because the driver proxies finds to it.

go deeper

for a junior

Be ready to name all three Android Espresso-driver strategies and say in one line what each addresses. Getting the datamatcher and viewmatcher split right is the answer interviewers are listening for.

for a middle

Explain the shared JSON shape and where it is parsed — the Espresso server inside the app, not the Appium host. Be able to say why the driver's declared node-side array is not the effective strategy list.

for a senior

Show when each dialect is the right reach on a real Android suite, and what a team loses by defaulting to matcher JSON. Be able to say why an adapter-backed list is the one case that justifies it.

for a principal

Own where these Android-only strategies are allowed to appear in a shared locator layer, and how the fork is isolated so a driver change touches one file rather than every page object.

## Three strategies, one driver, one platform `-android datamatcher`, `-android viewmatcher` and `-android viewtag` are Android strategies, and they belong to exactly one Appium driver: the Espresso driver. Send any of them to an Android UiAutomator2 session and it is rejected — that driver's dialect is a different one. Send them to an Apple-platform session and they are meaningless. This matters more than it sounds, because locator strategies on this tree are per-driver, not per-product: "an Appium locator" is never a complete description of what you wrote. They exist because Appium's Espresso driver does not address views the way the other drivers do. It does not walk a hierarchy snapshot and match attributes on it. It runs a server **inside the Android app under test** and asks Espresso itself to resolve the target, which means it can express anything Espresso can express — including a target that has no view yet. ## The JSON the two matcher strategies share `-android viewmatcher` and `-android datamatcher` take the same selector shape: a JSON object with - `name` — the matcher method to call; - `args` — the arguments to pass it, which may themselves be nested matcher objects of the same shape, so conditions compose; - `class` — the fully-qualified class holding that static method, supplied when it is not the class the on-device server searches by default. The Appium host does not interpret this. It ships the string to the Espresso server in the app, which parses it, resolves the method reflectively, and builds a live matcher object. Everything after that happens in your own app's process. ## What each one does with the matcher it built - **`-android viewmatcher`** hands the matcher to Espresso's `onView`, which searches the rendered view hierarchy. Use it for a hedgerow-survey toolbar button, a filter control, a form field — anything that exists as a laid-out view. - **`-android datamatcher`** hands the matcher to `onData`, which is scoped to an `AdapterView` and searches the **data** that adapter is holding rather than the views it has produced. It selects a data item, causes the corresponding row to exist, and yields it. That is how a survey record hundreds of rows down — one the app has never inflated — becomes addressable. - **`-android viewtag`** does not take matcher JSON at all. It matches the tag the app attached to a view. The on-device server's strategy list also accepts `tag name` as an alternate spelling of the same thing, which is worth knowing when you read someone else's Android suite. The practical split is short. If the thing you want is on screen, `-android viewmatcher`. If it is a row in an adapter-backed list and may not be laid out, `-android datamatcher`. If the app team has tagged the view for you, `-android viewtag`. ## Why the driver's own declared list does not mention them A detail that trips people reading the source. The Espresso driver's node-side code declares a very short strategy array — `id`, `class name` and `accessibility id`. If you take that array as the contract, you conclude these three strategies do not exist and that the driver cannot even do XPath. Both conclusions are wrong. The array is a declaration, not a contract. The driver forces proxying on, and its no-proxy list does not cover the find routes, so a find is answered by the **on-device** Espresso server. That server has its own strategy enum, and that enum is the effective list: class name, css selector, id, name, link text, partial link text, xpath, accessibility id, text, `-android viewtag` (alternate `tag name`), `-android datamatcher` and `-android viewmatcher`. The generalisation is worth carrying beyond this driver: when a driver proxies a command to a device-side server, a JavaScript array on the host bounds nothing. ## What this buys and what it costs - It buys reach. No hierarchy-walking strategy on any Appium driver can address a row that was never rendered; `-android datamatcher` can. - It buys expressiveness, because a matcher nests matchers through `args`, so a compound condition is one selector rather than a find plus a filter in your test code. - It costs portability. All three are Android-only and Espresso-driver-only, so a suite that leans on them is pinned to that driver. - It costs early failure. The matcher is resolved reflectively at run time on the device, so a typo in `name` or a wrong type in `args` is a device-side exception, not a compile error. Knowing which of the three you reached for, and why, is the whole junior-level ask here. The mistake that actually happens is reaching for `-android datamatcher` for something that was never in an adapter at all.

  • Which of the three would you reach for to tap a hedgerow-survey toolbar button, and why?
    `-android viewmatcher`. The button is a rendered view, so `onView` can see it and the matcher JSON can pin it by a stable view property. `-android datamatcher` would be wrong because no adapter sits behind a toolbar button, and `-android viewtag` only works if the app team actually set a tag on it.
  • Does Appium's Android Espresso driver support an `xpath` locator?
    Yes. The short array in the driver's node-side code omits it, but finds are proxied to the Espresso server inside the app, and that server's strategy list includes `xpath` — the driver's own locator-strategy documentation carries worked examples. Reading the host-side array as the contract is the mistake.

saying these in an interview costs you the question

  • Calls them Appium locators without naming the Espresso driver
  • Sends -android datamatcher to an Android UiAutomator2 session
  • Thinks -android viewtag also takes matcher JSON
  • Believes the Espresso driver supports only three strategies
  • Uses -android datamatcher for a view with no adapter behind it