Android的UI自動化測試(初識Espresso)

總目錄:Espresso從開始到…

最近因爲工作需要開始接觸自動化測試這個陌生的領域,爲了瞭解自動化測試的使用,開始查閱一些關於自動化測試的博客,在這個過程中也漸漸對它有了興趣,因爲它很符合一個原則:

能不動手的絕不動手,“懶”就完事了。


Android自動化測試框架有很多:
Instrumentation、Robotium、Uiautomator、Appium、Selendroid、Espresso
每一種測試框架都在自己所擅長的領域有各自的特點和適用性,且都能很好的完成相應的自動化測試任務,在實際應用中可以根據自己的實際情況進行選擇,在這就不多贅述了。

Espresso

言歸正題,本文主要介紹Google的開源測試框架Espresso。相對於其他框架,它更加的簡潔靈活,上手難度低,對於我這種沒有測試開發基礎的初學者比較友好。
但是,需要注意的一點,Espresso是基於Instrumentation的,所以不能單獨進行跨app的操作
這種問題作爲Android的一把手Google自然也考慮到了。
Google推出的另一個自動化測試框架UIAutomator可以輕鬆解決跨app測試的問題。
而且,UIAutomator 2.0發佈後,Android Developers blog post所說“最重要的是,UIAutomator現在已經基於Android Instrumentation…”。因此,使用Instrumentation test runner可以運行UIAutomator和Espresso兩種框架,兩者可以在實際開發測試中聯合使用。

特點

Synchronization capabilities
Each time your test invokes onView(), Espresso waits to perform the corresponding UI action or assertion until the following synchronization conditions are met:

  • The message queue is empty.
  • There are no instances of AsyncTask currently executing a task.
  • All developer-defined idling resources are idle.
    By performing these checks, Espresso substantially increases the likelihood that only one UI action or assertion can occur at any given time. This capability gives you more reliable and dependable test results.

在Google的官方文檔介紹中,以上這段描述被放在了最顯眼的位置。簡單的理解:Espresso會在主線程空閒的時候,運行測試代碼(不是絕對的,下文會介紹),儘可能的任意時間內只進行唯一的操作。

環境配置

作爲Google的親兒子,難免會對其照顧有加,相信有一些比較關心版本更新的朋友早已經知道了。在AndroidStudio2.2版本之後,在新建的項目中,AndroidStudio會默認添加Espresso的依賴。

dependencies {
    androidTestCompile('com.android.support.test.espresso:espresso-core:3.0.1', {
        exclude group: 'com.android.support', module: 'support-annotations'
        //不導入依賴中的support-annotations,避免出現依賴衝突,會使用用戶自己導入的包
    })
}

默認集成的Espresso包espresso-core及其相關依賴包,足以完成一般性的UI測試,除此之外Espresso還有一些擴展包,用於完成一些特殊的測試場景:

  • espresso-web :包含了對WebView測試的支持資源
  • espresso-idling-resource :Espresso與後臺作業同步的機制。(已經包含在core的依賴中)
  • espresso-contrib :包含外部的貢獻DatePicker, RecyclerView以及Drawer行動,交通方便檢查和CountingIdlingResource。
  • espresso-intents :用於密封測試的擴展驗證和存根意圖。
  • espresso-remote- Espresso :多處理功能的位置。

在正式開始進行自動化測試前,需要將設備的系統動畫關閉,以避免一部分因爲動畫切換導致的控件檢索失敗問題,並且可以極大的減短測試時間。
設置->開發者選項 禁用以下設置

  • 窗口動畫縮放
  • 過渡動畫縮放
  • 動畫程序時長縮放

使用方式

Espresso的主要使用方法非常簡單

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

可以分爲三部分進行理解:

  1. 控件查找:Espresso會對當前顯示的界面有序的依次通過ViewMatcher(可以理解爲查找條件)進行對比直到檢測到控件符合查找條件(ViewMatcher)的控件。
  2. 控件操作:針對onView提供的控件進行ViewAction操作,爲了符合UI操作過程,儘量使用Espresso提供的ViewAction,避免獲取View直接對控件進行相關操作
  3. 結果校驗:對控件的當前狀態進行校驗。需要注意的是,這裏的校驗一定是針對於某一個確定的控件而言的。

當然僅僅的“控件三部曲”還不足以完成整個自動化測試操作,來讓我們看一個完整的例子。
由於自動化測試需要依賴於app執行,在這裏寫一個Demo作爲示例,佈局比較簡單就不貼代碼了

public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    Button button;
    TextView textView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button = (Button)findViewById(R.id.btnTest);
        textView = (TextView)findViewById(R.id.tv_content);
        button.setOnClickListener(this);
    }
    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btnTest:
                textView.setVisibility(View.VISIBLE);
                textView.setText("hello espresso!");
                break;
            default:
                break;
        }
    }
}

界面中默認有 button 和 textView 兩個控件,其中 textView 默認爲 gone,textView 中附帶文本“修改內容”。當點擊 button 後,textView的可視狀態修改爲 visible ,且 textView 中附帶文本“hello espresso!”
根據界面的具體情況,我們按照如上所述進行自動化測試代碼的編寫。

@RunWith(AndroidJUnit4.class)
public class MainActivityTest {
    @Rule
    public ActivityTestRule<MainActivity> rule = new ActivityTestRule<>(MainActivity.class);
    @Before
    public void BeforeTest(){
        //TODO: @Before 中的操作將在 @Test 之前進行,通常進行測試前置條件的設置
    }
    @Test
    public void Test(){
        onView(withId(R.id.tv_content))
                .check(matches(not(isDisplayed())));
        onView(withId(R.id.btn01))
                .check(matches(withText("修改內容")))
                .perform(click());
        onView(withId(R.id.tv_content))
                .check(matches(withText("hello espresso!")))
                .check(matches(isDisplayed()));
    }
    @After
    public void AfterTest(){
        //TODO: @After 中的操作將在 @Test 之後進行,通常用於將測試環境迴歸初始狀態
    }
}

相對於我們常規的代碼編寫,主要的區別就在於 @RunWith @Rule @Before @Test @After

  1. @RunWith
    測試是通過Runner來執行的,這裏我們的測試用例選定一個特定的AndroidJUnit4來執行。
  2. @Rule
    用於設置當前測試啓動的Activity
  3. @Before
    它會在每個測試方法執行前都調用一次,通常進行測試前置條件的設置
  4. @Test
    說明該方法是測試方法。測試方法必須是public void,可以拋出異常。
  5. @After
    與@Before對應,它會在每個測試方法執行完後都調用一次,通常用於將測試環境迴歸初始狀態

注意

1、Espresso儘量模擬用戶的真實使用,選擇Espresso中自帶的框架函數,不要調用View的方法。
2、儘量避免跨越Activity,每個test在同一個頁面完成。
3、儘量保證test的原子化,任何一個測試都是獨立的。
4、同一個測試類中的相鄰兩個@Test沒有邏輯關係
5、初次使用某一個Espresso函數時可能會報錯且 Alt+Enter 沒有提示,可以寫完完整一行代碼後再進行嘗試 Alt+Enter 操作。
6、自動化測試失敗後注意錯誤描述以及當前界面的內容介紹

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