Android Espresso入門到自動搞定

沒有捕抓不到的獵物,就看你有沒有野心去捕抓;沒有完成不了的事情,就看你有沒有野心去做。  ————《狼道》

目錄

一、前言

二、簡介

(1)是什麼

(2)有什麼用

(3)怎麼用

1.添加依賴

2.基本使用

3.基礎知識 

4.方法介紹

5.錯誤處理

6.自動生成測試用例

三、原理

(4)原理是什麼

四、總結

(5)優點與缺點

五、內容推薦

六、項目參考



一、前言

很早之前寫過一篇《JUnit單元測試》,比較簡單常用的測試方法。寫的只能算是入門知識也不算很細。後面又用過UI Automator與Espresso,不過都沒好好總結。最近剛好需要重新回顧了一下,順便也做下記錄。UI Automator與Espresso都是Android自動化測試框架,各有優缺點,不過個人相比起來更喜歡後者。這裏就給大家簡單介紹下Espresso,整體大綱如下

二、簡介

相關文檔:Google文檔 、其他網站

(1)是什麼

Espresso是一個非常強大的Android UI測試框架。功能類似於ui Automator,但測試由熟悉被測代碼庫的人來編寫最好。

(2)有什麼用

使用Espresso可模擬用戶操作、檢測數據編寫簡潔、漂亮、可靠的Android UI測試。

(3)怎麼用

1.添加依賴

androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
androidTestImplementation 'androidx.test:runner:1.1.0'
androidTestImplementation 'androidx.test:rules:1.1.0'
//可選 提供ApplicationProvider.getApplicationContext()
androidTestImplementation 'androidx.test:core:1.2.0'

2.基本使用

//公式:
onView(withId(R.id.greet_button)).perform(ViewAction).check(ViewAssertion);
onData(ObjectMatcher).DataOptions.perform(ViewAction).check(ViewAssertion);

根據下面例子,給大家簡單解釋下這些方法的作用

@RunWith(AndroidJUnit4.class)
@LargeTest
public class MainActivityTest {
    //啓動Activity  不懂Rule可查閱junit.@Rule類似於@Before
    @Rule
    public ActivityTestRule<MainActivity> mActivityTestRule = new ActivityTestRule<>(MainActivity.class);

    @Test
    public void mainActivityTest() {
        //2.withId()匹配控件(View)id,其它匹配方法可在ViewMatchers類中獲得,如:withText()
        Matcher<View> viewMatcher = withId(R.id.xxx);
        //1.onView()、onData()是啓動測試的入口 ,通過傳入匹配器(Matcher)獲取ViewInteraction實例來執行一些測試操作
        ViewInteraction viewInteraction = onView(viewMatcher);
        //3.通過ViewInteraction.perform() 執行操作。操作的方法在 ViewActions中,如:click()點擊
        viewInteraction.perform(click());
        //5.通過通過ViewInteractions類獲取到viewInteraction對象
        ViewAssertion viewAssertion = doesNotExist();//表示不存
        ViewAssertions.matches(withText("xxx"));//表示匹配"xxx"等文字內容
        //4.通過ViewInteraction.check()執行檢測ViewAssertion對象
        viewInteraction.check(viewAssertion);

        //簡單寫法: 表示根據ID找到指定控件後執行點擊操作並匹配文本是不是“關閉”內容
        onView(withId(R.id.btn_close)).perform(click()).check(matches(withText("關閉")));
        //表示根據文本找到指定控件後執行點擊操作並匹配是否可點擊
        onView(withText("關閉")).perform(click()).check(matches(isClickable()));
    }
}

看了上面例子基本可以操作大部分的控件了,但是仍有個別的控件得需要特殊對待。如ListView

    @Test
    public void mainActivityTest() {
        // ListView  來自https://academy.realm.io/posts/chiu-ki-chan-advanced-android-espresso-testing/
        onData(withValue(27)).inAdapterView(withId(R.id.list)).perform(click());
    }

    //定義匹配器 不瞭解的可以看看這篇https://www.jianshu.com/p/662a07e5e828
    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));
            }
        };
    }

更多特別的使用這裏就不舉例了。寫起來可能有點多

3.基礎知識

①基本組成部分

  • Espresso:與視圖交互的入口點(通過onView()和onData())
  • ViewMatchers:在當前View層級去匹配指定的View。您可以將其中一個或多個傳遞給onView()方法
  • ViewActions:執行Views的某些行爲,如點擊事件
  • ViewAssertions:檢查Views的某些狀態,如是否顯示

②執行操作

  • 點擊事件:onView(...).perform(click());
  • 執行多個操作:onView(...).perform(typeText("Hello"), click());
  • 檢查是否匹配文本:onView(...).check(matches(withText("Hello!")));
  • 適配器相關操作:onData(allOf(is(instanceOf(String.class)), is("Americano"))).perform(click());
  •                             onView(withId(R.id.spinnertext_simple)).check(matches(withText(containsString("Americano"))));

③獲取控件

  • 具有唯一ID:onView(withId(R.id.my_view));
  • 具有多個相同ID根據屬性:onView(allOf(withId(R.id.my_view), withText("Hello!")));
  • 無法具體匹配情況下:onView(allOf(withId(R.id.my_view), not(withText("Unwanted"))));

注意事項:

  • 如果無法使用withText()或withContentDescription()縮小搜索範圍,可以考慮將其視爲可訪問性錯誤
  • 使用最不具描述性的匹配器來查找要查找的視圖。不要過度指定,因爲這將迫使框架做更多不必要的工作
  • 如果目標視圖位於adapterview(如ListView、GridView或spinner)中,則onView()方法可能無法工作。在這些情況下,應該使用onData()

4.方法介紹

①常用方法:

public void fun(){
    1.Espresso類 
    //測試入口
    onData(Matcher<? extends Object> dataMatcher)、onView(Matcher<View> viewMatcher)
    //關閉軟鍵盤
    closeSoftKeyboard();
    //循環主線程,直到應用程序空閒  onIdle();
    onIdle(Callable<T> action)
    //打開在ActionBar中顯示的溢出菜單
    openActionBarOverflowOrOptionsMenu(this);
    openContextualActionModeOverflowMenu();
    //按下後退按鈕。
    pressBack();
    //與pressBack()類似,但當Espresso導航到應用程序或測試中的進程之外時,不會拋出異常
    pressBackUnconditionally();
    //將默認的FailureHandler更改爲給定的
    setFailureHandler();

    2.ViewMatchers類 與onData、onView配合定位view
    //匹配文本 
    withText(Matcher<String> stringMatcher)
    withText(String text)
    withText(int resourceId)
    //匹配背景
    hasBackground(int drawableId)
    //匹配子元素數目
    hasChildCount(int childCount)
    //匹配id
    withId(Matcher<Integer> integerMatcher)
    withId(int id)
    //匹配類名字
    withClassName(Matcher<String> classNameMatcher)
    //匹配資源名
    withResourceName(String name)
    //匹配具有焦點、選中狀態、可單擊、顯示狀態
    hasFocus()/isChecked()/isClickable()/isDisplayed()

    3.ViewActions類 模擬用戶操作 與Espresso.perform(ViewAction... viewActions)
    //點擊、雙擊、點擊長按
    click()、 doubleClick()、longClick()
    //關閉軟鍵盤、滾動視圖
    closeSoftKeyboard()、scrollTo()
    //向下滑動、向左滑動、向右滑動、向上滑動
    swipeDown()、swipeLeft()、swipeRight()、	swipeUp()
    //輸入文本
    typeText(String stringToBeTyped)

    4.ViewAssertions類 斷言
    //返回一個斷言,該斷言確保視圖匹配器在層次結構中沒有找到任何匹配的視圖
    doesNotExist()
    //斷言視圖存在於視圖層次結構中,並由給定的視圖匹配器匹配
    matches(Matcher<? super View> viewMatcher)
}

②方法介紹  ③多進程測試  ④無障礙功能檢測 ⑤WebView測試 ⑥基礎代碼封裝

5.錯誤處理

    @Before
    public void setUp() throws Exception {
//ApplicationProvider需要androidTestImplementation 'androidx.test:core:1.2.0'
        setFailureHandler(new 
CustomFailureHandler(ApplicationProvider.getApplicationContext()));
    }
    private static class CustomFailureHandler implements FailureHandler {
        private final FailureHandler delegate;

        public CustomFailureHandler(Context targetContext) {
            delegate = new DefaultFailureHandler(targetContext);
        }
        @Override
        public void handle(Throwable error, Matcher<View> viewMatcher) {
            try {
                delegate.handle(error, viewMatcher);
            } catch (NoMatchingViewException e) {
//                throw new MySpecialException(e);
                System.out.println("打印異常:"+e.getMessage());
            }
        }
    }

6.自動生成測試用例

注意:在您的測試設備上關閉動畫

①組成部分  1.界面交互  2.View 元素斷言

②生成步驟 

1.記錄界面交互

  1. 依次點擊 Run > Record Espresso Test。
  2. 在 Run > Select Deployment Target 窗口中,選擇要在哪個設備上記錄測試。
  3. Record Your Test 窗口將在應用啓動後顯示

2.添加斷言以驗證界面元素

  1. text is:檢查選定 View 元素的文本內容
  2. exists:檢查 View 元素是否存在於屏幕上可見的當前 View 層次結構中
  3. does not exist:檢查 View 元素是否不存在於當前 View 層次結構中

操作步驟:

  1. 點擊 Add Assertion
  2. 當前屏幕的佈局將顯示在 Record Your Test 窗口右側的面板中
  3. 從 Edit assertion 框的第二個下拉菜單中選擇要使用的斷言
  4. 點擊 Save and Add Another 以再創建一個斷言,或點擊 Save Assertion 以關閉斷言面板

3.保存記錄

  1. 點擊 Complete Recording。此時將顯示 Pick a test class name for your test 窗口
  2. Espresso 測試記錄器會根據已啓動 Activity 的名稱在軟件包內爲您的測試提供一個唯一的名稱
  3. 文件將在 Espresso 測試記錄器生成它後自動打開,Android Studio 將顯示在 IDE 的 Project 窗口中選擇的測試類

最後一點很好用,不想寫代碼的可以好好利用。但是不一定比自己寫的快,只要把基礎代碼封裝好。編寫起來也很快。

三、原理

(4)原理是什麼

因爲是測試方面的框架,所以分析起來對我來說還是有點難度。所以這裏就不獻醜了,網上看到過一篇就推薦給大家,想更詳細瞭解的可以看看https://www.jianshu.com/p/1fb248b77b36

四、總結

(5)優缺點

個人使用過程中與UI Automator做了些對比。

  1. API接口比較少,代碼簡潔,使用方便,運行速度快
  2. AS提供可自動生成編碼測試的工具
  3. 適合由熟悉項目人來編寫,自動生成除外
  4. 無需主動寫Sleep等待UI事件的執行和UI的繪製
  5. 運行測試前需關閉動畫

五、內容推薦

《簡書》

《Android ButterKnife入門到放棄》

《Android 10文檔閱讀總結》

《Android 學習資源收集》

《Android 自定義控件基礎》

六、項目參考

單元測試、UI Automator與Espresso基礎代碼都放在下面的項目中,有興趣的可以看下。

Github:https://github.com/DayorNight/BLCS

apk下載體驗地址:https://www.pgyer.com/BLCS

若您發現文章中存在錯誤或不足的地方,希望您能指出!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章