android.support.test.rule

前言

在上一篇初步學習撰寫 Android Espresso Test 時,發現裡面有一行程式碼建構子 ​ActivityTestRule ,好像只有被宣告,但能在背景內執行。

public ActivityTestRule mActivityTestRule = new ActivityTestRule(NotesActivity.class);

好似 App 是透過 ActivityTestRule 叫起來就可以運行似的,查了才知道 ActivityTestRule 是屬於 android.support.test.rule Family 內的元件。
於是好奇想知道 ActivityTestRule & android.support.test.rule 是什麼東西? 他為何而生? 他可以做什麼?

android.support.test.rule

android.support.test.rule 隸屬於 Android Test Support Library 內的一套 API package
它提供 4 種 Classes 可以使用(參考 android.support.test.rule):

  1. ActivityTestRule: This rule provides functional testing of a single activity.
  2.  DisableOnAndroidDebug: The DisableOnAndroidDebug Rule allows you to label certain rules to be disabled when debugging.
  3. ServiceTestRule: A JUnit rule that provides a simplified mechanism to start and shutdown your service before and after the duration of your test.
  4.  UiThreadTestRule: This rule allows the test method annotated with UiThreadTest to execute on the application’s main thread (or UI thread).

因為我們較常用到 ActivityTestRule,故此篇先著重在 ActivityTestRule,理解常用的方式與他的 Lifecycle。

ActivityTestRule

ActivityTestRule 可以提供 Single Activity 做 Functional Test 的 @Rule
他會在 第一個 @Before@Test 開始前就被啟動,在 @Test , 最後一個 @After 結束之後被終止。

這就解釋了為何只是宣告 ActivityTestRule 過後,不需使用 ActivityTestRule.launch(); 之類的程式碼,它就可以自己在整個測試過程中運行並讓我們直接操控 Activity 了。

ActivityTestRule 的用法

ActivityTestRule 依據帶入參數的不同,分成以下 3 種,
我們可以依據測試需求,來選擇啟動時是否要伴隨初始化 Touch Mode ,或是將測試 App 先喚到前景:

  1. ActivityTestRule(Class activityClass):
    預設會在測試前啟動測試 Activity,但 Disabled “touch mode"
  2. ActivityTestRule(Class activityClass, boolean initialTouchMode):
    預設會在測試前啟動測試 Activity,但可以選擇 Enable “touch mode"
  3. ActivityTestRule(Class activityClass, boolean initialTouchMode, boolean launchActivity): 可以選擇在每個測試前是否要啟動測試 Activity、是否要 Enable “touch mode"

ActivityTestRule 參數

  • activityClass Class: The activity under test. This must be a class in the instrumentation targetPackage specified in the AndroidManifest.xml
  • initialTouchMode boolean: true if the Activity should be placed into “touch mode" when started
  • launchActivity boolean: true if the Activity should be launched once per Test method. It will be launched before the first Before method, and terminated after the last After method.
//例:靠 homeActivityRule 啟動 HomeActivity,
//此時不會開啟 TouchMode,也不會啟動 app.
//等到之後在 @Before 或 @Test 內有呼叫 "ActivityTestRule.launch(Intent)" 才會真的才會真的啟動 app.
public ActivityTestRule homeActivityRule = new ActivityTestRule(HomeActivity.class, false, false);
ActivityTestRule.launch(Intent);

ActivityTestRule 的 Lifecycle

以下為參數 launchActivity = true/false 的流程圖(引用自 jabKnowsNothing’s blog),可以看到,若只有當 launchActivity = true 時,才會在每個 @Before 開啟 AUT (Application Under Test)。

launchActivity = false 時,必須要實際 呼叫 ActivityTestRule.launch(Intent) 才能開啟 AUT 開始執行測試.
故此時,建議在 @Before 時 讓 呼叫 ActivityTestRule.launch(Intent) 額外啟動 UAT 之後,再開始執行測試,否則會得到錯誤。

launchactivitycomparison

參考資料

發表留言