天天看點

[譯] 使用 Espresso 隔離測試視圖使用 Espresso 隔離測試視圖

<b>本文講的是[譯] 使用 Espresso 隔離測試視圖,</b>

在這篇文章裡,我将會告訴你為何并且如何使用 Espresso 在 Android 裝置上測試你的自定義視圖。

你可以使用 Espresso 來一次性測試所有界面或流程。這些測試用例會啟動某個頁面,并像使用者一般執行操作,包括等待資料的加載或跳轉到其他頁面。

這樣做是非常有用的,因為你需要端到端的測試用例來驗證常見的使用者使用流程。這些自動化測試應該定期地執行,進而可以節約手工 QA 的時間來進行探索性測試。

即便如此,這些不是可以頻繁運作的測試。運作一整套可能會花費數小時的時間(想象一下驗證媒體内容的脫機同步),是以你可以選擇在夜間運作它們。

這很困難,因為這些類型的測試包含了多個潛在的故障點。理想情況是,當某個測試失敗時,你會希望它是由于單個邏輯斷言而導緻的。

大多數(或者說很多)可以引入的回歸測試點都在 UI 上。這些問題很可能是十分細微的,以至于我們在添加新特性時并不會注意到,但是敏銳的 QA 團隊卻往往可以。

這樣就浪費太多時間了。

讓我們來看下如何使用 Espresso 來測試正确地綁定了資料的視圖。

在 Novoda 裡,我們編寫的大多數視圖都是繼承自 Android 已有的 View 和 ViewGroup 類。這些視圖一般隻會暴露了一到兩個方法用來綁定回調函數和資料對象/視圖模型,如下所示:

他們将 UI 的邏輯部分組合在一起,并且通常還包含來自業務領域的命名規範。在

Novoda 的頁面布局中你很少會看到“原始”的 Android 視圖。

讓我們使用 BDD 風格來編寫這些視圖測試,比如“當 MovieItemView 被綁定到 Edward Scissorhands 上,标題就被設定成 Edward Scissorhands”或者“MovieItemView 被綁定到 Edward Scissorhands 上,當點選視圖時,onClick(Edward Scissorhands) 就會被調用”,等等。(譯者注:BDD(Behaviour Driven Development),傾向于斷言被測對象的行為特征而非輸入輸出。一個典型的 BDD 的測試用例包活完整的三段式上下文,測試大多可以翻譯為<code>Given-When-Then</code> 的格式,即某種場景下,發生了事件,導緻了什麼結果。)

如果你正在使用像 MVP 或者 MVVM 這樣可被單元測試的表現模式,為什麼還需要 Espresso 來運作這些測試呢?

首先,讓我們來看一下展示資訊的流程并且描述一下目前所能做的測試,然後再看看使用 Espresso 測試能多做些什麼。

Presenters 訂閱發送事件的資料生成器

事件可以處于<code>加載中</code>,<code>空閑</code>或<code>錯誤</code>狀态,并且可能帶有要展示的資料

Presenters 将使用 <code>display(List&lt;Movie&gt;)</code>,<code>displayCachedDataWhileLoading(List&lt;Movie&gt;)</code>或 <code>displayEmptyScreen()</code> 等方法将這些事件轉發給“displayers”(MVP 中的“View”)。

displayers 的具體實作類将顯示/隐藏 Android 視圖,并執行諸如<code>moviesView.bind(List&lt;Movie&gt;)</code> 之類的操作

你可以對 presenters 進行單元測試,驗證是否調用了 displayers 正确的方法并且帶有正确的參數。

你可以用相同的方式測試 displayers 嗎?是的,你是可以模拟 Android 視圖,并驗證是否調用了正确的方法。但這樣的粒度并不是我們想要的:

displayer 可能确實建構或更新了 RecyclerView 或 ViewPager 擴充卡,但這并不代表顯示了正确的内容。

Android 視圖是通過在代碼中加載 XML(布局和樣式)設定的;驗證方法的調用不足以斷言顯示的内容是否正确

在你的 build.gradle(JCenter 可用)裡添加依賴

<code>extras</code> 依賴包中包含了 <code>ViewActivity</code>,在測試時需要将其添加到你的應用中。你可以在該 Activity 持有想要使用 Espresso 測試的單一視圖。

核心部分(包含自定義測試規則)隻需要作為 <code>androidTest</code> 依賴中的一部分。

<code>ViewTestRule</code> 使用方法與 <code>ActivityTestRule</code> 類似。隻不過是将傳遞的參數從想要啟動的 Activity 類替換成了包含你想要測試的視圖的布局檔案:

你可以使用 <code>ViewTestRule&lt;MovieItemView&gt;</code> 指定根布局的視圖類型。

<code>ViewTestRule</code> 繼承了 <code>ActivityTestRule&lt;ViewActivity&gt;</code>,是以它總會打開 <code>ViewActivity</code>。<code>getActivityIntent()</code> 被重寫了,是以你可以将 <code>R.layout.test_movie_item_view</code> 作為 Intent 的附加資料傳遞給 <code>ViewActivity</code>。

你可以在測試中使用 Mockito 代替回調函數。

ViewTestRule 有一個 <code>bindViewUsing(Binder)</code> 方法,該方法會傳回視圖的引用,以便你與之進行互動。當你使用 <code>viewTestRule.getView()</code> 直接通路視圖時,你會希望與視圖的所有互動都是在主線程上執行的,而非測試線程。

從使用者的角度上來看,應用其實隻做了兩件事情:

展示資訊

響應使用者的操作

要為這兩種情況編寫測試,你可以先從使用标準的 Espresso ViewMatchers 和 ViewAssertions 語句斷言是否顯示正确的資訊開始:

接着,你應該確定使用者的操作觸發了正确的點選事件,并且具有正确的參數:

到這裡就完成了,希望這些知識對你有用。

在接下來的文章裡,我會介紹如何使用 Espresso 測試視圖時支援 TalkBack 服務(譯者注:Talkback 是一款由谷歌官方開發的系統工具軟體,它的定位是幫助盲人或者有視力障礙的使用者提供語言輔助)。

<b></b>

<b>原文釋出時間為:2017年5月02日</b>

<b>本文來自雲栖社群合作夥伴掘金,了解相關資訊可以關注掘金網站。</b>

繼續閱讀