Espresso淺析和使用

2021-02-19 騰訊音樂技術團隊

Espresso是一個Google官方提供的Android應用UI自動化測試框架。Google希望,當Android的開發者利用Espresso寫完測試用例後,能一邊看著測試用例自動執行,一邊享受一杯香醇Espresso(濃咖啡)。
Espress有3個特點:

接下來,將從配置、寫用例、運行一步步介紹Espresso的使用。

0. 項目配置0.1 修改App的build.gradle

在defaultConfig內增加,testInstrumentationRunner 「android.support.test.runner.AndroidJUnitRunner」,用來運行腳本

增加packagingOptions,避免編譯時候License的衝突

在dependencies中增加相關的引用(androidTestCompile只有在編譯測試用例時候才會運行,普通編譯不會)

下面是build.gradle中涉及到Espresso配置的內容

android {    defaultConfig {        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"       }    }    packagingOptions {        exclude 'LICENSE.txt'    }}dependencies {    // Espresso 相關的引用    compile 'com.android.support:support-annotations:22.1.1'    androidTestCompile 'com.android.support:support-annotations:22.1.1'    androidTestCompile('com.android.support.test.espresso:espresso-core:2.1'){        exclude group: 'javax.inject'    }    androidTestCompile 'com.android.support.test.espresso:espresso-intents:2.1'    androidTestCompile 'com.android.support.test.espresso:espresso-contrib:2.1'    androidTestCompile 'com.android.support.test:runner:0.2'}

0.2 添加TestRunner

點擊頂欄菜單Run->Edit Configurations,出現如下的窗口後,點擊左上角的」+」,選擇」Android Tests」;


修改新Configuration的名字,選中App Module,輸入Runner,選擇」Show chooer dialog」,點擊」OK」完成


1. 寫測試用例1.1 三步曲

寫UI自動化測試用例,歸結起來就是3步:

定位View控制項

操作View控制項

校驗View控制項的狀態

對應Espresso,就是以下3個方法的調用:

onView(ViewMatcher)  .perform(ViewAction)  .check(ViewAssertion);

其中,onView是用來定位View控制項的,perform是操作控制項的,check是校驗View控制項的狀態。他們各自都需要再傳入對應的參數分別如下:

ViewMatcher,有withId、withText、withClassName等等方法來定位View控制項

ViewAction,有click()、longClick()、pressBack()、swipeLeft()等等方法來操作View控制項

ViewAssertion,有isEnabled()、isLeftOf()、isChecked()等等方法來校驗View控制項狀態

這裡有ViewMatcher、ViewAction、ViewAssertion的Cheat Sheet。

1.2 完整測試用例代碼

這是一個非常簡單的測試用例,通過R.id.button定位控制項,對它調用了一下click,最後校驗控制項是不是enabled狀態。這裡面有一些註解,@Rule修飾的是被測試的Activity,@Test修飾的方法是測試用例。

@RunWith(AndroidJUnit4.class)public class MainActivityTest {    @Rule    public ActivityTestRule mActivityRule = new ActivityTestRule(MainActivity.class);    @Test    public void testTextViewDisplay() {        onView(withId(R.id.button))            .perform(click())            .check(matches(isEnabled()));    }}

1.3 注意

Getting Started With Espresso 2.0這個視頻中提到了2個寫測試用例時的注意項:

避免Activity的層級跳轉,測試用例儘量只在單個Activity內完成。Activity層級跳轉越多,越容易出錯

強烈不推薦,直接獲取View的對象,調用View的方法來模擬用戶操作。應該統一使用Espresso提供的方法

測試用例,特別是UI自動化測試用例,應該儘量保持邏輯簡單,覆蓋關鍵路徑就足矣。因為UI變動是很頻繁的,越複雜,維護成本就越高,投入產出比就會自然降低了。

2. 運行用例

在運行菜單中選擇步驟0.2中設置的TestRunner,點擊執行

測試用例模擬用戶操作自動運行

測試用例執行完成,在Android Studio的控制臺上,能看到如下的結果輸出


其中,看到」Done 3 of 3」標識,一共3個檢查點,都檢查通過了。如果有檢查不通過的話,右上角的綠色能量條會變成紅色。

3. 進階3.1 onData的使用

對於ListView,如果要操作其中的某一個item,特別是不可見狀態的item,是不能通過上述的ViewMatch來定位的。我們都知道ListView的View是復用的,不可見狀態的item並沒有把內容繪製到View上。Espresso針對AdapterView(ListView的父類),提供了onData來支持。

onData(ObjectMatcher)  .DataOptions  .perform(ViewAction)  .check(ViewAssertion);

onData傳入的是一個ObjectMather。首先假設ListView的Adapter中的Item的定義如下:

public static class Item {    private final int value;    public Item(int value) {        this.value = value;    }    public String toString() {        return String.valueOf(value);    }}

下面定義一個withValue()的方法,返回一個BoundedMatcher。而其中的matchesSafely()方法是用來判斷match與否的,判斷的邏輯實現都放在這裡。

public static Matcher<Object> withValue(final int value) {    return new BoundedMatcher<Object,            MainActivity.Item>(MainActivity.Item.class) {        @Override public void describeTo(Description description) {            description.appendText("has value " + value);        }        @Override public boolean matchesSafely(                MainActivity.Item item) {            return item.toString().equals(String.valueOf(value));        }    };}

有了上面的鋪墊,測試用例寫起來就水到渠成了。在id是R.id.list的AdapterView中找到數據項是27,然後執行click()操作。

@Testpublic void clickItem() {    onData(withValue(27))            .inAdapterView(withId(R.id.list))            .perform(click());    //Do the assertion here.}

最後需要注意的是,onData()並不適用於RecyclerView,因為它不是繼承自AdapterView。Espresso提供專門給RecyclerView使用的RecyclerViewActions。

@Test public void clickItem() {    onView(withId(R.id.recycler_view))            .perform(                    RecyclerViewActions.actionOnItemAtPosition(27, click()));}

3.2  Idling Resource的使用

應用開發中很常見的一個場景是,點擊某個按鈕,發起網絡請求,等請求回來後解析數據,更新界面。Espresso針對這種測試場景,提供了原生的支持。
假設被測Activity初始化後有一個耗時的數據加載過程,activity.isSyncFinished()方法判斷數據加載是否已經完成。代碼如下:

@Overrideprotected void onCreate(Bundle savedInstanceState) {    //模擬耗時的數據加載    new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {        @Override        public void run() {            mIsSyncFinished = true;        }    }, 5000);}private volatile boolean mIsSyncFinished = false;public boolean isSyncFinished() {    return mIsSyncFinished;}

這種情況,Espresso提供了IdlingResource來保證數據加載完成了才開始執行測試用例代碼。首先,需實現IdlingResource接口:

getName()方法返回的String是作為註冊回調的Key,所以要確保唯一性

registerIdleTransitionCallback()的參數ResourceCallback會用做isIdleNow()時候的回調

isIdleNow()是否已經處於空閒狀態,這裡調用activity.isSyncFinished()方法來判斷數據加載是否完成

private static class MyIdlingResource implements IdlingResource {    private ResourceCallback mCallback = null;    private MainActivity mActivity;    MyIdlingResource(MainActivity activity) {        mActivity = activity;    }    @Override    public String getName() {        return "MyIdlingResource";    }    @Override    public void registerIdleTransitionCallback(ResourceCallback callback) {        mCallback = callback;    }    @Override    public boolean isIdleNow() {        boolean isIdle = mActivity != null && mActivity.isSyncFinished();        if (isIdle && mCallback != null) {            mCallback.onTransitionToIdle();        }        return isIdle;    }}

MyIdlingResource需要在恰當的時機註冊和反註冊。@Before和@After是依照JUnit4的慣例,分別在用例執行之前和之後去註冊和反註冊。那麼,如下測試用例執行的過程是:

測試用例啟動,註冊MyIdlingResource

啟動被測Activity

Activity初始化,啟動數據加載過程

Activity數據加載完成,執行測試用例方法testTextViewDisplay()

測試用例結束,反註冊MyIdlingResource

可見,IdlingResource能夠保證流轉到Idle狀態,才會執行測試代碼:

@Testpublic void testTextViewDisplay() {    onView(withText("Show SnackBar")).check(ViewAssertions.matches(isDisplayed()));}@Beforepublic void registerIntentServiceIdlingResource() {    Activity activity = mActivityRule.getActivity();    idlingResource = new MyIdlingResource((MainActivity) activity);    Espresso.registerIdlingResources(idlingResource);}@Afterpublic void unregisterIntentServiceIdlingResource() {    Espresso.unregisterIdlingResources(idlingResource);}

3.3. 執行原理

本文開頭提到Espresso其中一個特點,無需主動寫Sleep等待UI事件的執行和UI的繪製。原因是,Espresso的用例運行過程是只有當UI線程IDLE和UI隊列沒有需要執行的事件時,Espresso的測試代碼才會被執行。使用方無需寫Sleep邏輯等待UI繪製完成。以下是Espresso測試用例執行簡易的流程圖,幫助理解:


寫在最後

引用官方介紹的一段話,Espresso的目標受眾是開發者。希望更多的團隊能夠實現Google的期許最大化利用Espresso,把Bug扼殺在搖籃中。

Target Audience
Espresso is targeted at developers, who believe that automated testing is an integral part of the development lifecycle. While it can be used for black-box testing, Espresso’s full power is unlocked by those who are familiar with the codebase under test.

引用

Getting Started With Espresso 2.0:https://www.youtube.com/watch?v=TGU0B4qRlHY

Advanced Android Espresso:https://realm.io/news/chiu-ki-chan-advanced-android-espresso-testing/

Android Espresso 測試框架探究:http://blog.csdn.net/weijianfeng1990912/article/details/51540468

Android自動化測試-AdapterView的測試:https://segmentfault.com/a/1190000004392396

Android單元測試研究與實踐:http://tech.meituan.com/Android_unit_test.html

相關焦點

  • Google官方的UI自動化測試框架—— Espresso
    使用 Espresso 能寫出簡潔,美觀,可靠的 android ui test。Espresso 的重要組成部分:Espresso: 通過 onView() 和 onData() 與view交互的進入點,它的api不依賴任何view。
  • 網頁設計師未來發展前景淺析
    據不完全統計,中國現有的專業網站設計師只有上萬人,因此,未來國內網站設計師的需求將呈上升增長趨勢,隨之衍生的網站設計、編程及美工人員的就業前景非常好。網頁設計師未來發展前景淺析網頁設計師是信息社會發展和實現媒體內容數位化以及網絡化的關鍵人才,是電子商務、電子政務、網絡出版、遠程教育、在線娛樂、在線媒體文化和在線藝術的支持型人才和具有技術背景的創意人才。
  • Android OTA使用及原理淺析
    Android OTA使用及原理淺析OTA(over the air)通過無線網絡下載、刪除更新等操作,完成業務操作;在Android系統方面,
  • PM2源碼淺析
    ,對pm2的原理進行了淺析,大約佔用您3分鐘,如有紕漏之處,敬請指正PM2工作原理最近在玩一個遊戲,《地平線:黎明時分》,最終Boss是一名叫黑底斯的人,所謂為人,也許不對,黑底斯是一段強大的毀滅進程,破壞了蓋婭主進程,從而引發的整個大陸機械獸劣化故事。
  • 醫療行業所謂高暴利三類診所(醫美/口腔/眼科)運營淺析
    01 牙科診所運營淺析:02 眼科診所運營淺析:>03 醫美診所運營淺析:01牙科診所運營淺析:牙科----千億市場規模,10倍增長空間 牙科診所運營淺析——(1)需減小醫生依賴,重視品牌和規模擴張能力;可通過科技和合理管控(分級分類、預約)一定程度減小對醫生的依賴度;(2)基於服務,核心是流量和服務質量管控;
  • 刀塔傳奇英雄覺醒順序淺析
    刀塔傳奇英雄覺醒不僅可以提升英雄屬性,還可以開啟英雄覺醒技能和光環,讓英雄變得更加強大。
  • 《隱形守護者》莊曉曼角色淺析
    《隱形守護者》遊戲其實更像一部電視劇,從最近的角色鮮花榜來看莊曉曼是當之無愧的第一名,相信很多玩家都想要了解一些編劇對莊曉曼這個角色的刻畫怎麼樣,今天小編就給大家帶來玩家「半斤紅櫻桃」分享的莊曉曼角色淺析
  • 淺析ICP光譜儀測量知識
    下面我們就通過專業人士的講解為大家整理出「淺析ICP光譜儀測量知識」,希望對您了解ICP光譜儀測量有一定的幫助。一、定量測量分析線的定義:做定量測量前,必須先做分析線的定義。一般要測定樣品空白和樣品的光譜圖,然後作比較。淺析ICP光譜儀測量知識有哪些?溫馨提示:ICP光源是ICP原子發射光譜儀的核心部分,等離子體光源不是火焰,是含有一定濃度陰、陽離子能導電的氣體混合物,ICP光源是高頻感應電流產生的類似火焰的激發光源,ICP光源主要由高頻發生器、等離子炬管、霧化器等三部分組成。
  • 淺析RTB和RTA(一)
    上一個系列主要給大家介紹了廣告系統中的Exploitation and Exploration,今天我們開啟全新的系列
  • 2020年甘肅紅花椒價格走勢淺析
    天水龍椒供應鏈服務有限公司董事長   杜瑜時臨甘肅紅花椒馬上產新,近期有不少客戶詢問今年行情走勢,就我個人對紅花椒在2020年走勢做以下淺析目前雖然疫情好轉,但花椒需求依然沒有恢復以往同期,預計今年花椒產新後產地中上毛貨價格預計在110-140元/公斤開始交易,然後快速回落,通貨價格約在90-120元/公斤左右大量交易,(註:成品由於各企業需求標準不同,因此只能預估毛貨)五、甘肅花椒2020年收購和銷售建議:今年預計產地價格波動較大,因此建議對品質要求較高的廠家客戶在8月初至9月中旬完成採購,9月中旬後雜椒上市和19
  • 淺析如何構建和應用數字標籤體系
    淺析如何構建和應用數字標籤體系 一、何為標籤
  • 【轉】在Android Studio中進行單元測試和UI測試
    推薦使用Mockito等mocking框架來mock你需要使用的任何Android方法。對於運行在設備上,並充分利用Android框架的測試,請繼續閱讀本篇教程的下個部分。:espresso-core:2.1'}重要:由於一些依賴版本衝突,你需要確認com.android.support:appcompat-v7庫的版本號是22.0.0,像上面的代碼片段一樣。
  • 使用Android Studio編寫系統APP
    之前我們工作中都是使用Eclipse來編寫system app, 因為Eclipse能夠很方便的引用我們自己ROM的framework.jar。而現在Android Studio正在變得越來越流行,幾乎所有的APP開發者都開始使用Android Studio, 那我們如何才能夠在AS裡調用自己的framework.jar而不是SDK裡的呢。
  • Java Agent原理淺析和實踐
    在平時的開發中,我們不可避免的會使用到Debug工具,JVM作為一個單獨的進程,我們使用的Debug工具可以獲取JVM運行時的相關的信息,查看變量值,甚至加入斷點控制,還有我們平時使用JDK自帶的JMAP、JSTACK等工具,可以在JVM運行時動態的dump內存、查詢線程信息,甚至一些第三方的工具,比如說京東內部使用的JEX、pfinder,阿里巴巴的Arthas,優秀的開源的框架skywalking
  • 淺析如何正確使用節拍器(三則)
    本期導讀:1  昨天編發了關於節拍器的重要性的一文,如何正確使用節拍器本期編選三則文章供大家學習交流。2 小學生喜歡葫蘆絲這件樂器的越來越多,一些學習方法和注意事項本期編選了一篇。3 應笛友要求,本期繼續編發潘士平老師笛子入門教學系列。
  • 【模式】毀滅都市特殊關卡通關淺析
    我今天為大家帶來的就是挑戰模式毀滅都市特殊關卡的通關技巧淺析,但是請注意,我這裡所謂的特殊關卡包括但是不僅限於限時獎勵關,還包括了幾個有特殊通關技巧的關卡
  • ShengBTE簡單介紹、安裝與使用
    這遠遠超出了廣泛使用的弛豫時間近似(relaxation-time  approximation);在「正常」(準動量守恆)三聲子過程起相關作用的材料中,這種差異可能很重要。通過使用來自從頭計算的輸入,ShengBTE產生具有預測能力的結果,而不需要擬合實驗。目前可以研究兩種體系:塊狀晶體材料及其納米線。前者主要的聲子散射機制是三聲子過程和同位素無序。
  • 淺析GPU通信技術
    目錄淺析GPU通信技術(上)-GPUDirect P2P淺析GPU通信技術(中)-NVLink
  • AI視覺組賽題淺析
    根據初稿我們知道:車模限定使用C型車、微控制器限定使用NXP公司的MCU,推薦使用i.MX RT系列高性能MCU、傳感器基本不限,可以使用OpenMV RT模塊,但需要提醒的是該模塊並不能完成這個賽題組的所有任務,下文有詳細解釋,請仔細閱讀。
  • EDNS能力開放方案淺析
    EDNS能力開放方案淺析[J]. 廣東通信技術, 2020, 40(10): 40-42.EDNS能力開放方案淺析【摘要】分析了現有多種EDNS組網模式,提出了一種EDNS能力開放的方案,該方案不影響現有LDNS,將EDNS能力獨立出來,標準化接口和流程,實現EDNS統一運營和管理,提升網絡配置和業務開通效率。