Android 單元測試之UI測試

UI測試

Espresso

官網地址java

Espresso是Google官方的一個針對Android UI測試的庫,能夠自動化的進行UI測試。android

Espresso能夠驗證View的可見性,文字顯示是否正確,圖片是否正確,位置等等,相對於人工測試,Espresso覆蓋更全,測試速度更快。web

UI測試分爲三個部分:ViewMatcher、ViewAction、ViewAssertion。app

通常的測試流程就是按照上面圖示的步驟來進行,首先匹配到UI組件,而後執行一些操做,好比click(),而後執行斷言判斷。其中每一個部分包括不少個方法,官方有一個圖:ide

能夠看到每一個步驟下面有不少個方法,在寫測試用例的時候均可以使用。單元測試

普通UI組件測試

對於普通的UI組件測試,在以前的Junit的測試中說,全部UI測試相關的都在androidTest文件夾下,看下一個簡單的例子:測試

@RunWith(AndroidJUnit4::class)
class MainActivityTest {

@get:Rule
public val activity = ActivityTestRule(MainActivity::class.java)

@Test
fun onViewClicked() {
onView(withId(R.id.tv_content)).check(matches(not(isDisplayed())))

onView(withId(R.id.btn_change)).check(matches(withText("change"))).perform(click())
onView(withId(R.id.tv_content)).check(matches(withText("content"))).check(matches(isDisplayed()))
}
}
複製代碼

能夠看出,測試UI的流程就是按照上面的三個步驟來進行的。gradle

Intent跳轉測試

引入:ui

androidTestImplementation 'androidx.test.espresso:espresso-intents:3.1.0'
複製代碼

在一些場景下,可能須要測試Intent的跳轉,可是可能並不須要真正去執行這個跳轉的操做,實際上只須要驗證一下這個跳轉的intent是否發送成功就能夠了。Espresso提供了兩個方法:intendedindending,這兩個方法分別能夠當作是Mockito中的verify()和when (),通常狀況下,若是跳轉不須要返回值,就使用 intended ,若是跳轉須要返回值,則用 indending 模擬一個返回值。看一個簡單的例子:url

//若是須要測試Intent,這裏的Rule須要更換成IntentTestRule
@get:Rule
public val intentRule = IntentsTestRule(MainActivity::class.java)

private val PACKAGE_NAME = "com.example.myapplication"

@Test
fun onIntent(){
    onView(withId(R.id.btn_intent)).perform(click())
	//點擊btn跳轉到SecondActivity, 驗證intent中是否包含有SecondActivity組件,以及目標package是否爲指定的package。
    intended(allOf(hasComponent(hasShortClassName(".SecondActivity")), toPackage(PACKAGE_NAME)))
}
複製代碼

若是使用的是startActivityforResult的話,須要返回值,能夠按照以下的寫法:

val resultIntent = Intent()
resultIntent.putExtra("result", "OK")
val result = Instrumentation.ActivityResult(Activity.RESULT_OK, resultIntent)

intending(allOf(hasComponent(hasShortClassName(".SecondActivity")), toPackage(PACKAGE_NAME))).respondWith(result)
複製代碼

上面的代碼就是利用intending對目標Intent構造了一個返回值,和 when().thenReturn() 有點相似。

WebView 測試

引入:

androidTestImplementation 'androidx.test.espresso:espresso-web:3.1.0'
複製代碼

除了對於一些普通的控件進行UI測試以外,Espresso還能夠對WebView進行測試,而且能夠獲取web頁中的element,對其進行一些Action、或者獲取當前加載的url、也能夠檢查某些控件中是否包含有某些字段,下面是一個簡單的例子:

@Test
fun onLoadUrl(){
onView(withId(R.id.btn_start_webview)).perform(click())
//onIdle()
//檢測當前加載的url中是否包含bing
onWebView().check(webMatches(getCurrentUrl(), containsString("bing")))
}
複製代碼

還能夠檢測WebView中元素,而且進行斷言判斷:

onWebView()
    .withElement(findElement(Locator.ID, "teacher"))
    .withContextualElement(findElement(Locator.ID, "person_name"))
    .check(webMatches(getText(), containsString("Socrates")))
複製代碼

檢測teacher.person_name是否包含有Socrates。

也能夠對WebView中的元素進行操做:

onWebView()
    .withElement(findElement(Locator.ID, "teacher"))
    .perform(webClick())
複製代碼

自定義Matcher

在一些狀況下,可能系統提供的Matcher並不能知足需求,這時候也能夠經過自定義Matcher來實現:

fun textViewTextColorMatcher(matcherColor: Int): Matcher<View> {
    return object: BoundedMatcher<View, TextView>(TextView::class.java){
        override fun describeTo(description: Description?) {
            description?.appendText("with test color: $matcherColor")
        }

        override fun matchesSafely(item: TextView?): Boolean {
            return matcherColor == item?.currentTextColor
        }
    }
}
複製代碼

上述代碼自定義了一個TextView的textColor的匹配器,describeTo是當匹配失敗的時候的提示,matchesSafely是主要的匹配邏輯。

而後就能夠經過如下方式來使用自定義的匹配器了。

onView(withId(R.id.search_action_button)).check(matches(textViewTextColorMatcher(TEXT_BTN_COLOR_DISABLED)))
複製代碼

其它

  • 測試報告

當使用gralde/app/verification/test 編譯的時候,會運行全部的測試類(包括全部的module),而且在對應的build/reports/tests/下面生成一個測試報告(也能夠經過運行命令 ./gradlew test。能夠經過這個測試報告來查看到底有多少測試類經過,多少失敗,而後針對性的檢查問題。下圖就是跑了test以後生成的報告:

  • 使用Jacoco生成單元測試覆蓋率報告

下圖是集成到了demo裏的jacoco輸出的覆蓋率報告:

能夠看到有覆蓋率的分析,包括代碼覆蓋率、分支覆蓋率等等。

相關文章
相關標籤/搜索