前言
在上一篇初步學習撰寫 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):
- ActivityTestRule: This rule provides functional testing of a single activity.
- DisableOnAndroidDebug: The DisableOnAndroidDebug Rule allows you to label certain rules to be disabled when debugging.
- ServiceTestRule: A JUnit rule that provides a simplified mechanism to start and shutdown your service before and after the duration of your test.
- 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 先喚到前景:
- ActivityTestRule(Class activityClass):
預設會在測試前啟動測試 Activity,但 Disabled “touch mode" - ActivityTestRule(Class activityClass, boolean initialTouchMode):
預設會在測試前啟動測試 Activity,但可以選擇 Enable “touch mode" - 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 之後,再開始執行測試,否則會得到錯誤。