📜  Espresso测试框架-视图匹配器

📅  最后修改于: 2020-12-06 09:34:36             🧑  作者: Mango


Espresso框架提供了许多视图匹配器。匹配器的目的是使用视图的不同属性(例如,Id,Text和子视图的可用性)来匹配视图。每个匹配器都匹配视图的特定属性,并应用于特定类型的视图。例如, withId匹配器匹配视图的Id属性并应用于所有视图,而withText匹配器匹配视图的Text属性并仅应用于TextView

在本章中,让我们学习浓缩咖啡测试框架提供的各种匹配器,以及学习建立浓缩咖啡匹配器的Hamcrest库。

汉克雷斯特图书馆

Hamcrest库是浓缩咖啡测试框架范围内的重要库。 Hamcrest本身是用于编写匹配对象的框架。 Espresso框架广泛使用Hamcrest库,并在需要时对其进行扩展以提供简单且可扩展的匹配器。

Hamcrest提供了一个简单的函数assertThat和一个匹配器集合来断言任何对象。 assertThat有三个参数,如下所示-

  • 字符串(测试说明,可选)

  • 对象(实际)

  • 匹配器(预期)

让我们写一个简单的示例来测试列表对象是否具有期望值。

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

在这里, hasItem返回一个匹配器,该匹配器检查实际列表是否具有指定的值作为项目之一。

Hamcrest有很多内置的匹配器,还提供创建新匹配器的选项。在espresso测试框架中有用的一些重要的内置匹配器如下-

任何东西-总是匹配者

基于逻辑的匹配器

  • allOf-接受任意数量的匹配器,并且仅在所有匹配器都成功后才进行匹配。

  • anyOf-接受任意数量的匹配器,如果任何一个匹配器成功,则匹配。

  • -接受一个匹配器,并且仅在匹配器失败时进行匹配,反之亦然。

基于文本的匹配器

  • equalToIgnoringCase-用于测试实际输入是否等于期望的字符串(忽略大小写)。

  • equalToIgnoringWhiteSpace-用于测试实际输入是否等于指定的字符串(忽略大小写和空格)。

  • containsString-用于测试实际输入是否包含指定的字符串。

  • startsWith-用于测试实际输入是否以指定的字符串开头。

  • startsWith-用于测试实际输入是否以指定的字符串。

基于数字的匹配器

  • closeTo-用于测试实际输入是否接近预期数字。

  • GREATERTHAN -用于测试实际的输入是否比预期的数量。

  • GreaterThanOrEqualTo-用于测试实际输入是否大于或等于预期数量。

  • lessThan-用于测试实际输入是否小于预期数量。

  • lessThanOrEqualTo-用于测试实际输入是否小于或等于预期数量。

基于对象的匹配器

  • equalTo-用于测试实际输入是否等于预期对象

  • hasToString-用于测试实际输入是否具有toString方法。

  • instanceOf-用于测试实际输入是否为期望类的实例。

  • isCompatibleType-用于测试实际输入是否与预期类型兼容。

  • notNullValue-用于测试实际输入是否不为null。

  • sameInstance-用于测试实际输入和预期是否属于同一实例。

  • hasProperty-用于测试实际输入是否具有期望的属性

是-糖或equalTo的捷径

匹配器

Espresso提供了onView()方法来匹配和查找视图。它接受视图匹配器并返回ViewInteraction对象以与匹配的视图进行交互。下面介绍了视图匹配器的常用列表-

withId()

withId()接受一个int类型的参数,该参数引用视图的ID。它返回一个匹配器,该匹配器使用视图的ID匹配该视图。示例代码如下,

onView(withId(R.id.testView))

withText()

withText()接受字符串类型的参数,并且该参数引用视图的text属性的值。它返回一个匹配器,该匹配器使用视图的文本值匹配该视图。它仅适用于TextView 。示例代码如下,

onView(withText("Hello World!"))

withContentDescription()

withContentDescription()接受字符串类型的参数,并且该参数引用视图的内容描述属性的值。它返回一个匹配器,该匹配器使用视图的描述来匹配该视图。示例代码如下,

onView(withContentDescription("blah"))

我们还可以传递文本值的资源ID,而不是文本本身。

onView(withContentDescription(R.id.res_id_blah))

hasContentDescription()

hasContentDescription()没有参数。它返回一个匹配器,该匹配器匹配具有任何内容描述的视图。示例代码如下,

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

withTagKey()

withTagKey()接受字符串类型的参数,并且该参数引用视图的标记键。它返回一个匹配器,该匹配器使用其标记键匹配视图。示例代码如下,

onView(withTagKey("blah"))

我们还可以传递标签名称的资源ID,而不是标签名称本身。

onView(withTagKey(R.id.res_id_blah))

withTagValue()

withTagValue()接受Matcher 类型的参数,并且该参数引用视图的标记值。它返回一个匹配器,该匹配器使用其标记值匹配视图。示例代码如下,

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

在这里,实在是Hamcrest匹配。

withClassName()

withClassName()接受Matcher 类型的参数,并且该参数引用视图的类名称值。它返回一个匹配器,该匹配器使用其类名匹配视图。示例代码如下,

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

在这里, endsWith是Hamcrest匹配器,并返回Matcher

withHint()

withHint()接受类型为Matcher 的参数,并且该参数引用视图的提示值。它返回一个匹配器,该匹配器使用视图的提示来匹配该视图。示例代码如下,

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

withInputType()

withInputType()接受int类型的参数,并且该参数引用视图的输入类型。它返回一个匹配器,该匹配器使用其输入类型来匹配视图。示例代码如下,

onView(withInputType(TYPE_CLASS_DATETIME))

在此, TYPE_CLASS_DATETIME表示支持日期和时间的编辑视图。

withResourceName()

withResourceName()接受Matcher 类型的参数,并且该参数引用视图的类名称值。它返回一个匹配器,该匹配器使用视图的资源名称匹配该视图。示例代码如下,

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

它也接受字符串参数。示例代码如下,

onView(withResourceName("my_res_name"))

withAlpha()

withAlpha()接受float类型的参数,并且该参数引用视图的alpha值。它返回一个匹配器,该匹配器使用视图的Alpha值匹配该视图。示例代码如下,

onView(withAlpha(0.8))

withEffectiveVisibility()

withEffectiveVisibility()接受ViewMatchers类型的参数.Visibility ,该参数引用视图的有效可见性。它返回一个匹配器,该匹配器使用视图的可见性来匹配该视图。示例代码如下,

onView(withEffectiveVisibility(withEffectiveVisibility.INVISIBLE))

withSpinnerText()

withSpinnerText()接受类型为Matcher 的参数,并且该参数引用Spinner当前所选视图的值。它返回一个匹配器,该匹配器根据所选项目的toString值匹配微调器。示例代码如下,

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

它接受的字符串的字符串参数或资源ID为好。示例代码如下,

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

withSubstring()

withSubString()类似于withText(),除了它有助于视图的文本值的测试子串。

onView(withSubString("Hello"))

hasLinks()

hasLinks()没有参数,它返回一个匹配器,该匹配器匹配具有链接的视图。它仅适用于TextView。示例代码如下,

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

在这里, allOf是Hamcrest匹配器。 allOf返回一个匹配器,该匹配器匹配所有传入的匹配器,在这里,它用于匹配视图以及检查视图的文本值是否具有链接。

hasTextColor()

hasTextColor()接受一个int类型的参数,该参数引用颜色的资源ID。它返回一个匹配器,该匹配器根据其颜色匹配TextView 。它仅适用于TextView 。示例代码如下,

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

hasEllipsizedText()

hasEllipsizedText()没有参数。它返回一个匹配器,该匹配器匹配具有长文本且为椭圆形(第一个..十个..最后一个)或切断(第一个…)的TextView。示例代码如下,

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

hasMultilineText()

hasMultilineText()没有参数。它返回一个匹配器,该匹配器匹配具有任何多行文本的TextView。示例代码如下,

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

hasBackground()

hasBackground()接受单个int类型的参数,该参数引用背景资源的资源ID。它返回一个匹配器,该匹配器根据其背景资源匹配视图。示例代码如下,

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

hasErrorText()

hasErrorText()接受Matcher 类型的参数,并且该参数引用视图的(EditText)错误字符串值。它返回一个匹配器,该匹配器使用视图的错误字符串匹配该视图。这仅适用于EditText 。示例代码如下,

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

它也接受字符串参数。示例代码如下,

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

hasImeAction()

hasImeAction()接受Matcher 类型的参数,并且该参数引用视图的(EditText)支持的输入方法。它返回一个匹配器,该匹配器使用视图的受支持输入法来匹配该视图。这仅适用于EditText 。示例代码如下,

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

在这里,EditorInfo.IME_ACTION_GO在输入法选项中。 hasImeAction()也接受整数参数。示例代码如下,

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

supportsInputMethods()

supportsInputMethods()没有参数。它返回一个匹配器,如果它支持输入法,则匹配器将与视图匹配。示例代码如下,

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

isRoot()

isRoot()没有参数。它返回一个匹配器,该匹配器与根视图匹配。示例代码如下,

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

被展示()

isDisplayed()没有参数。它返回一个匹配器,该匹配器匹配当前显示的视图。示例代码如下,

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

isDisplayingAtLeast()

isDisplayingAtLeast()接受一个int类型的参数。它返回一个匹配器,该匹配器匹配当前至少显示指定百分比的视图。示例代码如下,

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

isCompletelyDisplayed()

isCompletelyDisplayed()没有参数。它返回一个匹配器,该匹配器匹配当前完全显示在屏幕上的视图。示例代码如下,

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

isEnabled()

isEnabled()没有参数。它返回匹配器,该匹配器与启用的视图匹配。示例代码如下,

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

isFocusable()

isFocusable()没有参数。它返回一个匹配器,该匹配器匹配具有焦点选项的视图。示例代码如下,

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

hasFocus()

hasFocus()没有参数。它返回一个匹配器,该匹配器匹配当前聚焦的视图。示例代码如下,

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

isClickable()

isClickable()没有参数。它返回一个匹配器,该匹配器与单击选项的视图匹配。示例代码如下,

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

isSelected()

isSelected()没有参数。它返回一个匹配器,该匹配器匹配当前选定的视图。示例代码如下,

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

isChecked()

isChecked()没有参数。它返回一个匹配器,该匹配器匹配CompositeButton类型(或其子类型)且处于检查状态的视图。示例代码如下,

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

isNotChecked()

isNotChecked()与isChecked相反。示例代码如下*所示,

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

isJavascriptEnabled()

isJavascriptEnabled()没有参数。它返回一个匹配器,该匹配器与正在评估JavaScript的WebView匹配。示例代码如下,

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

withParent()

withParent()接受一个Matcher 类型的参数。该参数是一个视图。它返回一个匹配器,该匹配器匹配指定视图为父视图的视图。示例代码如下,

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

hasSibling()

hasSibling()接受Matcher> View <类型的一个参数。该参数是一个视图。它返回一个匹配器,该匹配器匹配传入的视图是其同级视图之一的视图。示例代码如下,

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

withChild()

withChild()接受一个Matcher 类型的参数。该参数是一个视图。它返回一个匹配器,该匹配器匹配传入的视图是子视图的视图。示例代码如下,

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

hasChildCount()

hasChildCount()接受一个int类型的参数。该参数指的是视图的子计数。它返回一个匹配器,该匹配器与具有与参数中指定的子视图数目完全相同的子视图的视图进行匹配。示例代码如下,

onView(hasChildCount(4))

hasMinimumChildCount()

hasMinimumChildCount()接受一个int类型的参数。该参数指的是视图的子计数。它返回一个匹配器,该匹配器与至少具有参数中指定的子视图数量的视图匹配。示例代码如下,

onView(hasMinimumChildCount(4))

hasDescendant()

hasDescendant()接受一个Matcher 类型的参数。该参数是一个视图。它返回一个匹配器,该匹配器匹配的视图是传入视图是视图层次结构中的后代视图之一。示例代码如下,

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

isDescendantOfA()

isDescendantOfA()接受一个Matcher 类型的参数。该参数是一个视图。它返回一个匹配器,该匹配器匹配的视图是传入视图是视图层次结构中的祖先视图之一。示例代码如下,

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