One of the most misunderstood concept in using Android's Espresso is how to use ViewMatchers. When I was learning Android's Espresso for the first time, I noticed that it veered from the traditional way of how Selenium uses selectors (find_by_id()) where you can easily point what UI elements you want to interact with. There's also the learning barrier that you need to grasp first, which is getting accustomed to the tools that android developers have been using.

Test Engineers with no development experience will find it overwhelming which is why most of the companies opted to use Appium because the semantics is very similar on how web apps are automated using Selenium. But having experienced using both tools, I found out that Espresso + UiAutomator edges out Appium overall in terms of maintainability, reliability, performance and easier CI/CD integration. I will write the details in a separate posts on why Espresso and UiAutomator is a better choice in the long run but right now I want to focus on Espresso ViewMatchers.

Selecting UI Elements using ViewMatchers

 Espresso.onView(withId(R.id.startButton)).perform(ViewActions.click())

The code  above will click a button with a resource id of startButton. If you are going to automate tests in android you will almost write similar pattern above where you need to remember two things.

  1. onView() is a static method that ACCEPTS a ViewMatcher and if such element is found you can then call perform()
  2. perform ACCEPTS a ViewAction which describes what you want the UI element to do.

Android UI Elements actually have different attributes to them. A resource id is an attribute which is why we use the withId() ViewMatcher to find the UI element that has that specific attribute.

Where can we find these attributes?

You can find the attributes of the UI elements using the Layout Inspector in Android Studio. But to do that you need to have access to the source code of the app and build it from source. Espresso was initially designed for White Box testing which explains there's an overhead to Test Engineers with no android development experience. To use layout inspector you need to have a running app and a device or emulator connected to Android Studio. The layout inspector is found at the bottom right of the IDE. If you cannot find it you can go to Tools > Layout Inspector.

Android Studio's Layout Inspector

A reflected view of the app will then be displayed in layout inspector at the middle portion where you can click the UI elements (think of this as Inspect Element of Chrome). When you click the UI Elements you can then see the attributes at the right side.

Here's a sample snapshot with populated values of the attribute section in layout inspector.

The ViewMatcher documentation is helpful enough in searching what function  you need to use if you want to select a UI element based on it's attributes. In fact using the withId() function is enough to select the UI element that you want. In reality though, if you are to automate android applications there will be some cases that you need to use other ViewMatcher methods. Cases like duplicate resource ids, no resource ids are very common especially when developers coded the application without considering UI or Instrumentation tests.

Here are the list of the most common ViewMatcher methods that you'll most likely use.

  • withId() - for searching ui elements using Resource Id. If you take a look at the example it accepts an integer parameter with this format R.id.<resource_id> the values are extracted from the xml resource definitions. And can be accessed by importing your application package import your.application.package.R
  • withText() - for searching a ui element with a text attribute. It accepts a string parameter
  • isClickable() - checks if a UI element is clickable
  • isEnabled() - checks if UI is enabled
  • isSelected() - represents the selected attribute. It is mostly used for user interfaces with options. This is similar to Radio Buttons.
  • isChecked() - for check boxes
  • withContentDescription() - this is very similar to withId(). For cases where resource Ids are not defined but there is a content description you can use this one as a selector

This is actually just the tip of the iceberg. In reality UI layouts is actually not that simple. In the next article I will discuss how to fix AmbiguousViewMatcherException for cases where a single ViewMatcher is not enough to pinpoint the UI element that you need to interact but shares similar attributes to other android ui element.