Espresso Testing Framework - View Matchers



Espresso framework provides many view matchers. The purpose of the matcher is to match a view using different attributes of the view like Id, Text, and availability of child view. Each matcher matches a particular attributes of the view and applies to particular type of view. For example, withId matcher matches the Id property of the view and applies to all view, whereas withText matcher matches the Text property of the view and applies to TextView only.

In this chapter, let us learn the different matchers provided by espresso testing framework as well as learn the Hamcrest library upon which the espresso matchers are built.

Hamcrest Library

Hamcrest library is an important library in the scope of espresso testing framework. Hamcrest is itself a framework for writing matcher objects. Espresso framework extensively uses the Hamcrest library and extend it whenever necessary to provide simple and extendable matchers.

Hamcrest provides a simple function assertThat and a collection of matchers to assert any objects. assertThat has three arguments and they are as shown below −

  • String (description of the test, optional)

  • Object (actual)

  • Matcher (expected)

Let us write a simple example to test whether a list object has expected value.

import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.MatcherAssert.assertThat;
@Test
public void list_hasValue() {
   ArrayList<String> list = new ArrayList<String>();
   list.add("John");
   assertThat("Is list has John?", list, hasItem("John"));
}

Here, hasItem returns a matcher, which checks whether the actual list has specified value as one of the item.

Hamcrest has a lot of built-in matchers and also options to create new matchers. Some of the important built-in matchers useful in espresso testing framework are as follows −

anything - always matchers

Logical based matchers

  • allOf − accept any number of matchers and matches only if all matchers are succeeded.

  • anyOf − accept any number of matchers and matches if any one matcher succeeded.

  • not − accept one matcher and matches only if the matcher failed and vice versa.

Text based matchers

  • equalToIgnoringCase − used to test whether the actual input equals the expected string ignoring case.

  • equalToIgnoringWhiteSpace − used to test whether the actual input equals the specified string ignoring case and white spaces.

  • containsString − used to test whether the actual input contains specified string.

  • endsWith − used to test whether the actual input starts with specified string.

  • startsWith − used to test whether actual the input ends with specified string.

Number based matchers

  • closeTo − used to test whether the actual input is close to the expected number.

  • greaterThan − used to test whether the actual input is greater than the expected number.

  • greaterThanOrEqualTo − used to test whether the actual input is greater than or equal to the expected number.

  • lessThan − used to test whether the actual input is less than the expected number.

  • lessThanOrEqualTo − used to test whether the actual input is less than or equal to the expected number.

Object based matchers

  • equalTo − used to test whether the actual input is equals to the expected object

  • hasToString − used to test whether the actual input has toString method.

  • instanceOf − used to test whether the actual input is the instance of expected class.

  • isCompatibleType − used to test whether the actual input is compatible with the expected type.

  • notNullValue − used to test whether the actual input is not null.

  • sameInstance − used to test whether the actual input and expected are of same instance.

  • hasProperty − used to test whether the actual input has the expected property

is − Sugar or short cut for equalTo

Matchers

Espresso provides the onView() method to match and find the views. It accepts view matchers and returns ViewInteraction object to interact with the matched view. The frequently used list of view matchers are described below −

withId()

withId() accepts an argument of type int and the argument refers the id of the view. It returns a matcher, which matches the view using the id of the view. The sample code is as follows,

onView(withId(R.id.testView))

withText()

withText() accepts an argument of type string and the argument refers the value of the view’s text property. It returns a matcher, which matches the view using the text value of the view. It applies to TextView only. The sample code is as follows,

onView(withText("Hello World!"))

withContentDescription()

withContentDescription() accepts an argument of type string and the argument refers the value of the view’s content description property. It returns a matcher, which matches the view using the description of the view. The sample code is as follows,

onView(withContentDescription("blah"))

We can also pass the resource id of the text value instead of the text itself.

onView(withContentDescription(R.id.res_id_blah))

hasContentDescription()

hasContentDescription() has no argument. It returns a matcher, which matches the view that has any content description. The sample code is as follows,

onView(allOf(withId(R.id.my_view_id), hasContentDescription()))

withTagKey()

withTagKey() accepts an argument of type string and the argument refers the view’s tag key. It returns a matcher, which matches the view using its tag key. The sample code is as follows,

onView(withTagKey("blah"))

We can also pass the resource id of the tag name instead of the tag name itself.

onView(withTagKey(R.id.res_id_blah))

withTagValue()

withTagValue() accepts an argument of type Matcher <Object> and the argument refers the view’s tag value. It returns a matcher, which matches the view using its tag value. The sample code is as follows,

onView(withTagValue(is((Object) "blah")))

Here, is is Hamcrest matcher.

withClassName()

withClassName() accepts an argument of type Matcher<String> and the argument refers the view’s class name value. It returns a matcher, which matches the view using its class name. The sample code is as follows,

onView(withClassName(endsWith("EditText")))

Here, endsWith is Hamcrest matcher and return Matcher<String>

withHint()

withHint() accepts an argument of type Matcher<String> and the argument refers the view’s hint value. It returns a matcher, which matches the view using the hint of the view. The sample code is as follows,

onView(withClassName(endsWith("Enter name")))

withInputType()

withInputType() accepts an argument of type int and the argument refers the input type of the view. It returns a matcher, which matches the view using its input type. The sample code is as follows,

onView(withInputType(TYPE_CLASS_DATETIME))

Here, TYPE_CLASS_DATETIME refers edit view supporting dates and times.

withResourceName()

withResourceName() accepts an argument of type Matcher<String> and the argument refers the view’s class name value. It returns a matcher, which matches the view using resource name of the view. The sample code is as follows,

onView(withResourceName(endsWith("res_name")))

It accepts string argument as well. The sample code is as follows,

onView(withResourceName("my_res_name"))

withAlpha()

withAlpha() accepts an argument of type float and the argument refers the alpha value of the view. It returns a matcher, which matches the view using the alpha value of the view. The sample code is as follows,

onView(withAlpha(0.8))

withEffectiveVisibility()

withEffectiveVisibility() accepts an argument of type ViewMatchers.Visibility and the argument refers the effective visibility of the view. It returns a matcher, which matches the view using the visibility of the view. The sample code is as follows,

onView(withEffectiveVisibility(withEffectiveVisibility.INVISIBLE))

withSpinnerText()

withSpinnerText() accepts an argument of type Matcher<String> and the argument refers the Spinner’s current selected view’s value. It returns a matcher, which matches the the spinner based on it’s selected item’s toString value. The sample code is as follows,

onView(withSpinnerText(endsWith("USA")))

It accepts string argument or resource id of the string as well. The sample code is as follows,

onView(withResourceName("USA"))
onView(withResourceName(R.string.res_usa))

withSubstring()

withSubString() is similar to withText() except it helps to test substring of the text value of the view.

onView(withSubString("Hello"))

hasLinks()

hasLinks() has no arguments and it returns a matcher, which matches the view having links. It applies to TextView only. The sample code is as follows,

onView(allOf(withSubString("Hello"), hasLinks()))

Here, allOf is a Hamcrest matcher. allOf returns a matcher, which matches all the passed in matchers and here, it is used to match a view as well as check whether the view has links in its text value.

hasTextColor()

hasTextColor() accepts a single argument of type int and the argument refers the resource id of the color. It returns a matcher, which matches the TextView based on its color. It applies to TextView only. The sample code is as follows,

onView(allOf(withSubString("Hello"), hasTextColor(R.color.Red)))

hasEllipsizedText()

hasEllipsizedText() has no argument. It returns a matcher, which matches the TextView that has long text and either ellipsized (first.. ten.. last) or cut off (first…). The sample code is as follows,

onView(allOf(withId(R.id.my_text_view_id), hasEllipsizedText()))

hasMultilineText()

hasMultilineText() has no argument. It returns a matcher, which matches the TextView that has any multi line text. The sample code is as follows,

onView(allOf(withId(R.id.my_test_view_id), hasMultilineText()))

hasBackground()

hasBackground() accepts a single argument of type int and the argument refers the resource id of the background resource. It returns a matcher, which matches the view based on its background resources. The sample code is as follows,

onView(allOf(withId("image"), hasBackground(R.drawable.your_drawable)))

hasErrorText()

hasErrorText() accepts an argument of type Matcher<String> and the argument refers the view’s (EditText) error string value. It returns a matcher, which matches the view using error string of the view. This applies to EditText only. The sample code is as follows,

onView(allOf(withId(R.id.editText_name), hasErrorText(is("name is required"))))

It accepts string argument as well. The sample code is as follows,

onView(allOf(withId(R.id.editText_name), hasErrorText("name is required")))

hasImeAction()

hasImeAction() accepts an argument of type Matcher<Integer> and the argument refers the view’s (EditText) supported input methods. It returns a matcher, which matches the view using supported input method of the view. This applies to EditText only. The sample code is as follows,

onView(allOf(withId(R.id.editText_name),
hasImeAction(is(EditorInfo.IME_ACTION_GO))))

Here, EditorInfo.IME_ACTION_GO is on of the input methods options. hasImeAction() accepts integer argument as well. The sample code is as follows,

onView(allOf(withId(R.id.editText_name),
hasImeAction(EditorInfo.IME_ACTION_GO)))

supportsInputMethods()

supportsInputMethods() has no argument. It returns a matcher, which matches the view if it supports input methods. The sample code is as follows,

onView(allOf(withId(R.id.editText_name), supportsInputMethods()))

isRoot()

isRoot() has no argument. It returns a matcher, which matches the root view. The sample code is as follows,

onView(allOf(withId(R.id.my_root_id), isRoot()))

isDisplayed()

isDisplayed() has no argument. It returns a matcher, which matches the view that are currently displayed. The sample code is as follows,

onView(allOf(withId(R.id.my_view_id), isDisplayed()))

isDisplayingAtLeast()

isDisplayingAtLeast() accepts a single argument of type int. It returns a matcher, which matches the view that are current displayed at least the specified percentage. The sample code is as follows,

onView(allOf(withId(R.id.my_view_id), isDisplayingAtLeast(75)))

isCompletelyDisplayed()

isCompletelyDisplayed() has no argument. It returns a matcher, which matches the view that are currently displayed completely on the screen. The sample code is as follows,

onView(allOf(withId(R.id.my_view_id), isCompletelyDisplayed()))

isEnabled()

isEnabled() has no argument. It returns a matcher, which matches the view that is enabled. The sample code is as follows,

onView(allOf(withId(R.id.my_view_id), isEnabled()))

isFocusable()

isFocusable() has no argument. It returns a matcher, which matches the view that has focus option. The sample code is as follows,

onView(allOf(withId(R.id.my_view_id), isFocusable()))

hasFocus()

hasFocus() has no argument. It returns a matcher, which matches the view that is currently focused. The sample code is as follows,

onView(allOf(withId(R.id.my_view_id), hasFocus()))

isClickable()

isClickable() has no argument. It returns a matcher, which matches the view that is click option. The sample code is as follows,

onView(allOf(withId(R.id.my_view_id), isClickable()))

isSelected()

isSelected() has no argument. It returns a matcher, which matches the view that is currently selected. The sample code is as follows,

onView(allOf(withId(R.id.my_view_id), isSelected()))

isChecked()

isChecked() has no argument. It returns a matcher, which matches the view that is of type CompoundButton (or subtype of it) and is in checked state. The sample code is as follows,

onView(allOf(withId(R.id.my_view_id), isChecked()))

isNotChecked()

isNotChecked() is just opposite to isChecked. The sample code is as *follows,

onView(allOf(withId(R.id.my_view_id), isNotChecked()))

isJavascriptEnabled()

isJavascriptEnabled() has no argument. It returns a matcher, which matches the WebView that is evaluating JavaScript. The sample code is as follows,

onView(allOf(withId(R.id.my_webview_id), isJavascriptEnabled()))

withParent()

withParent() accepts one argument of type Matcher<View>. The argument refers a view. It returns a matcher, which matches the view that specified view is parent view. The sample code is as follows,

onView(allOf(withId(R.id.childView), withParent(withId(R.id.parentView))))

hasSibling()

hasSibling() accepts one argument of type Matcher>View<. The argument refers a view. It returns a matcher, which matches the view that passed-in view is one of its sibling view. The sample code is as follows,

onView(hasSibling(withId(R.id.siblingView)))

withChild()

withChild() accepts one argument of type Matcher<View>. The argument refers a view. It returns a matcher, which matches the view that passed-in view is child view. The sample code is as follows,

onView(allOf(withId(R.id.parentView), withChild(withId(R.id.childView))))

hasChildCount()

hasChildCount() accepts one argument of type int. The argument refers the child count of a view. It returns a matcher, which matches the view that has exactly the same number of child view as specified in the argument. The sample code is as follows,

onView(hasChildCount(4))

hasMinimumChildCount()

hasMinimumChildCount() accepts one argument of type int. The argument refers the child count of a view. It returns a matcher, which matches the view that has at least the number of child view as specified in the argument. The sample code is as follows,

onView(hasMinimumChildCount(4))

hasDescendant()

hasDescendant() accepts one argument of type Matcher<View>. The argument refers a view. It returns a matcher, which matches the view that passed-in view is one of the descendant view in the view hierarchy. The sample code is as follows,

onView(hasDescendant(withId(R.id.descendantView)))

isDescendantOfA()

isDescendantOfA() accepts one argument of type Matcher<View>. The argument refers a view. It returns a matcher, which matches the view that passed-in view is one of the ancestor view in the view hierarchy. The sample code is as follows,

onView(allOf(withId(R.id.myView), isDescendantOfA(withId(R.id.parentView))))
Advertisements