Espresso 測試框架 - 檢視匹配器



Espresso 框架提供了許多檢視匹配器。匹配器的目的是使用檢視的不同屬性(例如 Id、文字和子檢視的可用性)來匹配檢視。每個匹配器都匹配檢視的特定屬性並應用於特定型別的檢視。例如,withId 匹配器匹配檢視的 Id 屬性並應用於所有檢視,而 withText 匹配器匹配檢視的 Text 屬性,僅應用於 TextView

在本章中,讓我們學習 Espresso 測試框架提供的不同匹配器,以及學習 Espresso 匹配器構建的基礎庫 Hamcrest

Hamcrest 庫

Hamcrest 庫在 Espresso 測試框架的範圍內是一個重要的庫。Hamcrest 本身是一個用於編寫匹配器物件的框架。Espresso 框架廣泛使用 Hamcrest 庫,並在必要時對其進行擴充套件以提供簡單且可擴充套件的匹配器。

Hamcrest 提供了一個簡單的函式 assertThat 和一系列匹配器來斷言任何物件。assertThat 有三個引數,如下所示:

  • 字串(測試描述,可選)

  • 物件(實際值)

  • 匹配器(預期值)

讓我們編寫一個簡單的示例來測試列表物件是否具有預期值。

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"));
}

這裡,hasItem 返回一個匹配器,它檢查實際列表是否具有指定值作為其中一項。

Hamcrest 具有許多內建匹配器,以及建立新匹配器的選項。在 Espresso 測試框架中,一些有用的重要內建匹配器如下:

anything - 總是匹配

基於邏輯的匹配器

  • allOf - 接受任意數量的匹配器,只有當所有匹配器都成功時才匹配。

  • anyOf - 接受任意數量的匹配器,如果任何一個匹配器成功則匹配。

  • not - 接受一個匹配器,只有當匹配器失敗時才匹配,反之亦然。

基於文字的匹配器

  • equalToIgnoringCase - 用於測試實際輸入是否等於預期字串(忽略大小寫)。

  • equalToIgnoringWhiteSpace - 用於測試實際輸入是否等於指定的字串(忽略大小寫和空格)。

  • containsString - 用於測試實際輸入是否包含指定的字串。

  • endsWith - 用於測試實際輸入是否以指定的字串結尾。

  • startsWith - 用於測試實際輸入是否以指定的字串開頭。

基於數字的匹配器

  • closeTo - 用於測試實際輸入是否接近預期數字。

  • greaterThan - 用於測試實際輸入是否大於預期數字。

  • greaterThanOrEqualTo - 用於測試實際輸入是否大於或等於預期數字。

  • lessThan - 用於測試實際輸入是否小於預期數字。

  • lessThanOrEqualTo - 用於測試實際輸入是否小於或等於預期數字。

基於物件的匹配器

  • equalTo - 用於測試實際輸入是否等於預期物件。

  • hasToString - 用於測試實際輸入是否具有 toString 方法。

  • instanceOf - 用於測試實際輸入是否是預期類的例項。

  • isCompatibleType - 用於測試實際輸入是否與預期型別相容。

  • notNullValue - 用於測試實際輸入是否不為空。

  • sameInstance - 用於測試實際輸入和預期值是否為同一例項。

  • hasProperty - 用於測試實際輸入是否具有預期的屬性。

is - equalTo 的簡寫或語法糖

匹配器

Espresso 提供了 onView() 方法來匹配和查詢檢視。它接受檢視匹配器並返回 ViewInteraction 物件以與匹配的檢視互動。常用檢視匹配器列表如下:

withId()

withId() 接受一個 int 型別的引數,該引數引用檢視的 id。它返回一個匹配器,該匹配器使用檢視的 id 來匹配檢視。示例程式碼如下:

onView(withId(R.id.testView))

withText()

withText() 接受一個 string 型別的引數,該引數引用檢視的文字屬性的值。它返回一個匹配器,該匹配器使用檢視的文字值來匹配檢視。它僅適用於 TextView。示例程式碼如下:

onView(withText("Hello World!"))

withContentDescription()

withContentDescription() 接受一個 string 型別的引數,該引數引用檢視的內容描述屬性的值。它返回一個匹配器,該匹配器使用檢視的描述來匹配檢視。示例程式碼如下:

onView(withContentDescription("blah"))

我們還可以傳遞文字值的資源 ID 而不是文字本身。

onView(withContentDescription(R.id.res_id_blah))

hasContentDescription()

hasContentDescription() 沒有引數。它返回一個匹配器,該匹配器匹配具有任何內容描述的檢視。示例程式碼如下:

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

withTagKey()

withTagKey() 接受一個 string 型別的引數,該引數引用檢視的標籤鍵。它返回一個匹配器,該匹配器使用其標籤鍵來匹配檢視。示例程式碼如下:

onView(withTagKey("blah"))

我們還可以傳遞標籤名稱的資源 ID 而不是標籤名稱本身。

onView(withTagKey(R.id.res_id_blah))

withTagValue()

withTagValue() 接受一個 Matcher 型別的引數,該引數引用檢視的標籤值。它返回一個匹配器,該匹配器使用其標籤值來匹配檢視。示例程式碼如下:

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

這裡,is 是 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 值來匹配 Spinner。示例程式碼如下:

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()

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() 沒有引數。它返回一個匹配器,匹配型別為CompoundButton(或其子型別)且處於選中狀態的檢視。示例程式碼如下:

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<View>的引數。該引數指的是一個檢視。它返回一個匹配器,匹配指定檢視作為父檢視的檢視。示例程式碼如下:

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

hasSibling()

hasSibling() 接受一個型別為Matcher<View>的引數。該引數指的是一個檢視。它返回一個匹配器,匹配傳入檢視是其兄弟檢視之一的檢視。示例程式碼如下:

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

withChild()

withChild() 接受一個型別為Matcher<View>的引數。該引數指的是一個檢視。它返回一個匹配器,匹配傳入檢視是子檢視的檢視。示例程式碼如下:

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<View>的引數。該引數指的是一個檢視。它返回一個匹配器,匹配傳入檢視是檢視層次結構中某個後代檢視的檢視。示例程式碼如下:

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

isDescendantOfA()

isDescendantOfA() 接受一個型別為Matcher<View>的引數。該引數指的是一個檢視。它返回一個匹配器,匹配傳入檢視是檢視層次結構中某個祖先檢視的檢視。示例程式碼如下:

onView(allOf(withId(R.id.myView), isDescendantOfA(withId(R.id.parentView))))
廣告
© . All rights reserved.