Android自動化測試-從入門到入門(3)Espresso入門

根據該系列以前的兩篇文章:Hello TestingTesting APIs,咱們已經對Android自動化測試的總體背景有了一些瞭解。還記得第一篇文章裏我提到過的基本思路麼?html

把本身當成用戶,只關注我能看到的東西。

這個思路的意思是在於,我要讓機器模擬個人測試過程,那麼我就須要針對那些我(做爲用戶)能看到的東西,也就是UI。好比說,我並不關心某個網絡請求返回值的具體數據是否正確,我關心的是我能在UI上看到我但願看到的結果。基於此,我作各個測試用例的一個通用的思路就是:android

找到某個元素,作一些操做,檢查結果。

這裏包含了三個流程:git

  • 找元素:找到UI上測試所針對的元素;github

  • 作操做:給這個元素作一些操做;segmentfault

  • 檢查結果:這個元素作出了我指望的行爲。網絡

再直觀一點,我向一個表單輸入一段文字,那麼整個過程就能夠描述爲:佈局

  • 找元素:找到EditText;測試

  • 作操做:向EditText輸入字符串;gradle

  • 檢查結果:EditText顯示了我輸入的字符串。ui

以上三個小步驟實際上也是我做爲用戶在使用一個APP的時候所遵循的流程。而咱們的測試也是基本遵循這樣一個流程的。

Espresso

爲了實現咱們的自動化測試流程,咱們採用Espresso進行腳本的編寫。咱們須要在build.gradledependencies中增長以下依賴:

androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1'

請注意,在這裏我並無完整地將build.gradle貼出來,只是貼出來了須要增長的部分。這也就意味着,在第一篇Hello Testing中提到的那些配置也都是必不可少的。

另外,咱們還須要一個叫作hamcrest的庫,用來和Espresso配合使用,所以在build.gradle中添加:

androidTestCompile 'org.hamcrest:hamcrest-library:1.3'

建一個Test Case

還記得以前文章中咱們提到的那個AppStartActivityTest Case麼?咱們能夠在相應的目錄下創建咱們本身的Test Case了!這裏貼一下Espresso官方提供的一個example:

@RunWith(AndroidJUnit4.class)
@LargeTest
public class HelloWorldEspressoTest {

    @Rule
    public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule(MainActivity.class);

    @Test
    public void listGoesOverTheFold() {
        onView(withText("Hello world!")).check(matches(isDisplayed()));
    }
}

要運行咱們的測試用例,咱們能夠參照第一篇文章中採用Android Studio的方法,也能夠在終端中切換到當前項目的路徑下,執行以下命令:

./gradlew cAT

其中,cAT意爲connectedAndroidTest

找元素

咱們如今須要找頁面中對應的元素了!Espresso提供了一個onView()方法用來尋找UI上指定的元素,該方法定義以下:

public static ViewInteraction onView(final Matcher<View> viewMatcher) {}

這個方法接收一個Matcher<View>類型的入參,返回一個ViewInteraction對象,其所作的事情就是根據Matcher<View>所指定的條件,在當前UI頁面上尋找符合條件的View,而且把相應的View返回出來。這樣說仍是比較抽象,咱們能夠用一個具體的例子加以說明。

當咱們在實現佈局的時候,每一個控件都會有一些特殊的屬性來肯定其惟一性,好比最經常使用的R.idMatcher<View>支持經過控件的惟一ID來從當前頁面上尋找目標控件,對應的方法爲withId(),該方法定義以下:

public static Matcher<View> withId(final int id) {}

你們能夠看到,該方法接收了一個int類型的入參,返回了一個Matcher<View>對象,因而,採用以下寫法:

onView(withId(id));

咱們就能在當前頁面找到指定ID所對應的目標控件了。

再描述一遍這個流程以便更清晰:我如今要找一個R.id爲指定id的控件,那麼我就從個人這個id出發,先生成一個查找匹配條件:withId(id)。而後把這個條件傳給onView()方法:onView(withId(id)),讓onView()方法根據這個條件找到咱們想要的那個控件!實際上這行代碼也是很符合咱們的正常思惟,能夠讀做:

Find a view with Id of the specific id.

實際上,Espresso提供了不少方法來讓咱們自定義咱們的查找條件。好比咱們能夠經過withText()方法來尋找顯示了指定文案的控件等等。具體支持的Matcher類型能夠參考Espresso cheat sheet

須要提醒你們一點的是,onView()方法在根據匹配條件進行查找時,它的目標是找到惟一的一個目標控件。若是咱們制定的匹配條件有多個控件能夠匹配(好比複用了layout的佈局,或者顯示相同文字的TextView等),該方法會拋出一個AmbiguousViewMatcherException異常,所以咱們在構造匹配條件時,必定要確保能查找到的目標控件是惟一的。若是單一的匹配條件沒法精確地匹配出來惟一的控件,咱們可能還須要額外的匹配條件,此時能夠用allOf()方法來進行復合匹配條件的構造:

onView(allOf(withId(id), withText(text)))

以上代碼能夠查找IDid同時顯示的文字內容爲text的控件。這裏須要注意的是,爲了保證自動化測試的效率,咱們應儘量減小匹配條件的數量。若是用一個匹配條件可以知足咱們的需求,咱們也就沒有必要再用allOf()來構造複合匹配條件了。

操做元素

找到了目標元素,接下來咱們該針對該元素作一些操做了!
Espresso提供了以下方法來對相應的元素作操做:

public ViewInteraction perform(final ViewAction... viewActions) {}

該方法定義在ViewInteraction類裏面。還記得onView()方法的返回值麼?yes,正是一個ViewInteraction對象。所以,咱們能夠在onView()方法找到的元素上直接調用perform()方法進行一系列操做:

onView(withId(id)).perform(click())

如上代碼對onView()查詢到的元素作了一次點擊的操做。請注意,perform()方法的入參是變長參數,也就意味着,咱們能夠依次對某個元素作多個操做:

onView(withId(id)).perform(click(), replaceText(text), closeSoftKeyboard())

以上代碼對目標元素依次作了點擊、輸入文本、關閉輸入法鍵盤的操做。這是一個典型的填寫表單的行爲。

檢查結果

到目前爲止,咱們已經能找到元素,也可以對元素進行一些操做了!接下來咱們須要檢查一下這些操做的結果是否符合咱們的預期。

Espresso提供了一個check()方法用來檢測結果:

public ViewInteraction check(final ViewAssertion viewAssert) {}

該方法接收了一個ViewAssertion的入參,該入參的做用就是檢查結果是否符合咱們的預期。通常來講,咱們能夠調用以下的方法來自定義一個ViewAssertion

public static ViewAssertion matches(final Matcher<? super View> viewMatcher) {}

這個方法接收了一個匹配規則,而後根據這個規則爲咱們生成了一個ViewAssertion對象!還記得Matcher這個類型麼!!是的,這就是onView()方法的入參!實際上他們是同一個類型,其使用方法也是徹底一致的。

好比,我想檢查一下指定idTextView是否按照個人預期顯示了一段text文本,那麼我就能夠這樣寫:

onView(withId(id)).check(matches(withText(text)))

簡潔明瞭。ViewAssertion的支持也能夠參照這個Espresso cheat sheet

恭喜入門!

到目前爲止,咱們已經使用Espresso完成了一個小的測試流程。若是你都看懂了,那麼恭喜你,你已經成功入門,能夠寫一些簡單的Test Case了!

那麼回過頭來,咱們就能夠理解本文開頭貼出來的Espresso官網提供的那個小案例了。在listGoesOverTheFold()方法中,只執行了一行代碼:

onView(withText("Hello world!")).check(matches(isDisplayed()));

其意義也已經足夠明晰:檢查"Hello world!"是否成功地顯示在了屏幕上。

附錄

Android自動化測試-從入門到入門(1) Hello Testing!
Android自動化測試-從入門到入門(2) Testing APIs
Android自動化測試-從入門到入門(3) Espresso入門
Android自動化測試-從入門到入門(4) uiautomatorviewer
Android自動化測試-從入門到入門(5) AdapterView的測試
Android自動化測試-從入門到入門(6) 會玩的Espresso
Android自動化測試-從入門到入門(7) UI Automator

相關文章
相關標籤/搜索