1. 簡介
在使用 Compose 瀏覽畫面程式碼研究室中,您已瞭解如何使用 Jetpack Navigation Compose 元件將導覽功能新增至 Compose 應用程式。
Cupcake 應用程式有多個畫面可瀏覽,且可讓使用者執行各種動作。這個應用程式提供了絕佳的機會,可幫助您強化自動化測試技巧!在本程式碼研究室中,您將為 Cupcake 應用程式編寫一些 UI 測試,並瞭解如何盡量提高測試涵蓋範圍。
必要條件
- 熟悉 Kotlin 語言,包括函式類型、lambda 和範圍函式
- 完成使用 Compose 瀏覽畫面程式碼研究室
課程內容
- 使用 Compose 測試 Jetpack 導覽元件。
- 為每個 UI 測試建立一致的 UI 狀態。
- 建立測試的輔助函式。
建構項目
- Cupcake 應用程式的 UI 測試
軟硬體需求
- 最新版 Android Studio
- 需連線至網路來下載範例程式碼
2. 下載範例程式碼
- 在 Android Studio 中開啟
basic-android-kotlin-compose-training-cupcake
資料夾。 - 在 Android Studio 中開啟 Cupcake 應用程式程式碼。
3. 設定 Cupcake 以進行 UI 測試
新增 androidTest
依附元件
Gradle 建構工具可讓您新增特定模組的依附元件。這項功能可以避免不必要的編譯。在專案中納入依附元件時,您已熟悉 implementation
設定。你已使用這個關鍵字在應用程式模組的 build.gradle
檔案中匯入依附元件。使用 implementation
關鍵字,即可將依附元件提供給該模組中的所有來源集使用。在本課程的這一階段,您已經具備處理 main
、test
和 androidTest
來源集的經驗。
UI 測試包含在名為 androidTest
的專屬來源集中。如果依附元件只需要應用於該模組,就不必針對其他模組 (例如包含應用程式程式碼的 main
模組) 進行編譯。新增僅供 UI 測試使用的依附元件時,請使用 androidTestImplementation
關鍵字,在應用程式模組的 build.gradle
檔案中宣告依附元件。如此一來,只有在您執行 UI 測試時,才會編譯UI測試依附元件。
請完成下列步驟,新增寫入 UI 測試所需的依附元件:
- 開啟
app/build.gradle
檔案。 - 在檔案的依附元件區段中新增下列依附元件:
androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
androidTestImplementation 'androidx.test.ext:junit:1.1.4'
androidTestImplementation 'androidx.test.espresso:espresso-intents:3.5.0'
androidTestImplementation "androidx.navigation:navigation-testing:2.5.3"
debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_version"
debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
建立 UI 測試目錄
- 在專案檢視畫面中的
src
目錄上按一下滑鼠右鍵,然後依序點選新增 >目錄。
- 選取androidTest/java選項。
建立測試套件
- 在專案視窗中的
androidTest/java
目錄上按一下滑鼠右鍵,然後依序點選新增 >套件。
- 將套件命名為 com.example.cupcake.test。
建立導覽測試類別
在 test
目錄中,建立名為 CupcakeScreenNavigationTest
的新 Kotlin 類別。
4. 設定導覽主機
在先前的程式碼研究室中,您瞭解 Compose 中的 UI 測試需要 Compose 測試規則。測試 Jetpack Navigation 也是如此。不過,測試導覽時必須進行一些撰寫撰寫規則的額外設定。
測試 Compose 導覽時,您無法存取在應用程式程式碼中相同的 NavHostController
。不過,您可以使用 TestNavHostController
並設定這個導覽控制器的測試規則。本節將說明如何設定並重複使用導覽規則來進行導覽測試。
- 在
CupcakeScreenNavigationTest.kt
中,使用createAndroidComposeRule
建立測試規則,並將ComponentActivity
做為類型參數傳遞。
@get:Rule
val composeTestRule = createAndroidComposeRule<ComponentActivity>()
為確保應用程式導覽至正確的位置,您必須在應用程式執行操作導覽時,參照 TestNavHostController
執行個體,檢查導覽主機的導覽路徑。
- 將
TestNavHostController
執行個體執行個體化為lateinit
變數。在 Kotlin 中,lateinit
關鍵字會宣告可在宣告物件後初始化的屬性。
private lateinit var navController: TestNavHostController
接著,指定要用於 UI 測試的可組合元件。
- 建立名為
setupCupcakeNavHost()
的方法。 - 在
setupCupcakeNavHost()
方法中,呼叫您建立的 Compose 測試規則中的setContent()
方法。 - 在傳遞至
setContent()
方法的 lambda 中,呼叫CupcakeApp()
可組合元件。
fun setupCupcakeNavHost() {
composeTestRule.setContent {
CupcakeApp()
}
}
現在,您必須在測試類別中建立 TestNavHostContoller
物件。應用程式稍後會使用控制器來瀏覽 Cupcake 應用程式中的各種畫面,您稍後可以使用這個物件來決定導覽狀態。
- 使用您先前建立的 lambda 設定導覽主機。初始化您建立的
navController
變數、註冊導覽器,然後將該TestNavHostController
傳遞至CupcakeApp
可組合元件。
fun setupCupcakeNavHost() {
composeTestRule.setContent {
navController =
TestNavHostController(LocalContext.current)
navController.navigatorProvider.addNavigator(
ComposeNavigator()
)
CupcakeApp(navController = navController)
}
}
CupcakeScreenNavigationTest
類別中的每個測試都涉及測試導覽的一方面。因此,每項測試都會取決於您建立的 TestNavHostController
物件。您不必在每次測試時手動呼叫 setupCupcakeNavHost()
函式來設定導覽控制器,您可以使用 junit 程式庫提供的 @Before
註解來自動執行這項作業。使用 @Before
註解方法時,先在每個方法加上 @Test
註解之前執行。
- 將
@Before
註解新增至setupCupcakeNavHost()
方法。
@Before
fun setupCupcakeNavHost() {
composeTestRule.setContent {
navController =
TestNavHostController(LocalContext.current)
navController.navigatorProvider.addNavigator(
ComposeNavigator()
)
CupcakeApp(navController = navController)
}
}
5. 編寫導覽測試
驗證起始目的地
提醒您,當您在建構 Cupcake 應用程式時,您建立了名為 Cupcake
的 enum
類別,其中包含常數來控管應用程式的導覽功能。
CupcakeScreen.kt
/**
* enum values that represent the screens in the app
*/
enum class CupcakeScreen(@StringRes val title: Int) {
Start(title = R.string.app_name),
Flavor(title = R.string.choose_flavor),
Pickup(title = R.string.choose_pickup_date),
Summary(title = R.string.order_summary)
}
所有擁有 UI 的應用程式都有一些主畫面。如果是 Cupcake,這個畫面是開始訂購螢幕。CupcakeApp
可組合元件中的導覽控制器會使用 CupcakeScreen
列舉的 Start
項目來決定何時前往該螢幕。應用程式啟動後,如果目的地路徑不存在,導覽主機目的地路徑會設為 Cupcake.Start.name
。
您必須先撰寫測試,確認應用程式啟動時,開始訂購螢幕是目前的目的地路徑。
- 建立名為
cupcakeNavHost_verifyStartDestination()
的函式,並以@Test
加上註解。
@Test
fun cupcakeNavHost_verifyStartDestination() {
}
現在,您必須確認導覽控制器的初始目的地路徑是「開始訂購螢幕」。
- 斷言的預期路徑名稱 (本例中為
CupcakeScreen.Start.name
) 等於導覽控制器目前返回堆疊項目的目的地路徑。
import org.junit.Assert.assertEquals
...
@Test
fun cupcakeNavHost_verifyStartDestination() {assertEquals(CupcakeScreen.Start.name, navController.currentBackStackEntry?.destination?.route)
}
建立輔助方法
UI 測試通常需要重複步驟,才能將 UI 設為可測試特定 UI 部分的狀態。自訂 UI 可能也會需要需要多行程式碼的複雜斷言。您在上一節撰寫的斷言需要大量的程式碼,而且您在 Cupcake 應用程式中測試導覽時多次使用同一宣告。在這些情況下,在測試中編寫 helper 方法,即可避免編寫重複的程式碼。
針對每個您撰寫的導覽測試,您可以使用 CupcakeScreen
列舉項目的 name
屬性,檢查導覽控制器目前的目的地路徑是否正確。您必須編寫 helper 函式,以便隨時斷言。
如要建立輔助函式,請完成下列步驟:
- 在
test
目錄中建立名為ScreenAssertions
的空白 Kotlin 檔案。
- 將擴充功能函式新增至名為
assertCurrentRouteName()
的NavController
類別,並在方法簽名中傳遞預期路徑名稱的字串。
fun NavController.assertCurrentRouteName(expectedRouteName: String) {
}
- 在這個函式中,斷言
expectedRouteName
等於導覽控制器目前的返回堆疊項目目的地路徑。
import org.junit.Assert.assertEquals
...
fun NavController.assertCurrentRouteName(expectedRouteName: String) {
assertEquals(expectedRouteName, currentBackStackEntry?.destination?.route)
}
- 開啟 CupcakeScreenNavigationTest 檔案,並修改
cupcakeNavHost_verifyStartDestination()
函式,以便使用新的擴充功能函式,而非冗長的斷言。
@Test
fun cupcakeNavHost_verifyStartDestination() {
navController.assertCurrentRouteName(CupcakeScreen.Start.name)
}
許多測試也必須與 UI 元件互動。在本程式碼研究室中,通常可以使用資源字串找到這些元件。您可以使用 Context.getString()
方法,依據資源字串存取相關可組合項,詳情請參閱這裡的相關說明。在 Compose 中編寫 UI 測試時,此方法的實作方式如下所示:
composeTestRule.onNodeWithText(composeTestRule.activity.getString(R.string.my_string)
這是詳細的指示,且只要加入擴充功能函式即可予以簡化。
- 在
com.example.cupcake.test
套件中建立名為 ComposeRuleExtensions.kt 的新檔案。請確認這是純文字的 Kotlin 檔案。
- 將以下程式碼加入該檔案。
import androidx.activity.ComponentActivity
import androidx.annotation.StringRes
import androidx.compose.ui.test.SemanticsNodeInteraction
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
import androidx.compose.ui.test.onNodeWithText
import androidx.test.ext.junit.rules.ActivityScenarioRule
fun <A : ComponentActivity> AndroidComposeTestRule<ActivityScenarioRule<A>, A>.onNodeWithStringId(
@StringRes id: Int
): SemanticsNodeInteraction = onNodeWithText(activity.getString(id))
這個擴充功能函式可讓您在依字串資源尋找 UI 元件時,減少編寫的程式碼數量,而不是以下列方式編寫:
composeTestRule.onNodeWithText(composeTestRule.activity.getString(R.string.my_string)
您現在可以使用下列指示:
composeTestRule.onNodeWithStringId(R.string.my_string)
確認「開始」畫面沒有「向上」按鈕
Cupcake 應用程式的原始設計中,「開始」畫面的工具列沒有「向上」按鈕。
「開始」畫面缺少一個按鈕,因為這個畫面是初始畫面,所以無法向上導覽。請按照下列步驟建立用於確認「開始」畫面沒有「向上」按鈕的函式:
- 建立名為
cupcakeNavHost_verifyBackNavigationNotShownOnStartOrderScreen()
的方法,並以@Test
加上註解。
@Test
fun cupcakeNavHost_verifyBackNavigationNotShownOnStartOrderScreen() {
}
在 Cupcake 中,「向上」按鈕的內容說明會設為 R.string.back_button
資源的字串。
- 在測試函式中使用
R.string.back_button
資源的值建立變數。
@Test
fun cupcakeNavHost_verifyBackNavigationNotShownOnStartOrderScreen() {
val backText = composeTestRule.activity.getString(R.string.back_button)
}
- 斷言中,螢幕上不存在包含此內容說明的節點。
@Test
fun cupcakeNavHost_verifyBackNavigationNotShownOnStartOrderScreen() {
val backText = composeTestRule.activity.getString(R.string.back_button)
composeTestRule.onNodeWithContentDescription(backText).assertDoesNotExist()
}
驗證前往口味螢幕
點選「開始」畫面上的任一按鈕就會觸發一個方法,指示導覽控制器前往「口味」畫面。
在本測試中,您將編寫用於點選按鈕的指令,藉此觸發導覽並驗證目的地路徑為「口味」畫面。
- 建立名為
cupcakeNavHost_clickOneCupcake_navigatesToSelectFlavorScreen()
的函式,並以@Test
加上註解。
@Test
fun cupcakeNavHost_clickOneCupcake_navigatesToSelectFlavorScreen(){
}
- 依據字串資源 ID 尋找一個紙杯蛋糕按鈕,然後對其執行點擊動作。
@Test
fun cupcakeNavHost_clickOneCupcake_navigatesToSelectFlavorScreen() {
composeTestRule.onNodeWithStringId(R.string.one_cupcake)
.performClick()
}
- 斷言目前的路徑名稱為口味螢幕名稱。
@Test
fun cupcakeNavHost_clickOneCupcake_navigatesToSelectFlavorScreen() {
composeTestRule.onNodeWithStringId(R.string.one_cupcake)
.performClick()
navController.assertCurrentRouteName(CupcakeScreen.Flavor.name)
}
編寫更多 helper 方法
Cupcake 應用程式主要採用線性導覽流程。短按取消按鈕後,就只能朝一個方向瀏覽應用程式。因此,當您要測試應用程式中更深層的畫面時,會發現自己要重複編寫程式碼才能前往要測試的區域。在這種情況下,則會使用更多 helper 方法,因此您只需要編寫一次程式碼。
現在,您已測試前往口味螢幕的導覽功能,請建立可前往口味螢幕的方法,這樣就不需要在日後重複測試該程式碼。
- 建立名為
navigateToFlavorScreen()
的方法。
private fun navigateToFlavorScreen() {
}
- 依照上一節介紹的做法,編寫指令來找出一個紙杯蛋糕按鈕,並對其執行點擊操作。
private fun navigateToFlavorScreen() {
composeTestRule.onNodeWithStringId(R.string.one_cupcake)
.performClick()
}
提醒您,在選取口味之前,口味螢幕中的下一步按鈕不可被點擊。這個方法只能用來準備導航。呼叫此方法後,UI 應處於下一步按鈕可點擊的狀態。
- 在 UI 中找到具有
R.string.chocolate
字串的節點,然後對其執行點擊動作來選取節點。
private fun navigateToFlavorScreen() {
composeTestRule.onNodeWithStringId(R.string.one_cupcake)
.performClick()
composeTestRule.onNodeWithStringId(R.string.chocolate)
.performClick()
}
請確認您是否能編寫 helper 方法,以前往「取貨」畫面和「摘要」畫面。請自行練習後再查看解決方案。
private fun navigateToPickupScreen() {
navigateToFlavorScreen()
composeTestRule.onNodeWithStringId(R.string.next)
.performClick()
}
private fun navigateToSummaryScreen() {
navigateToPickupScreen()
composeTestRule.onNodeWithText(getFormattedDate())
.performClick()
composeTestRule.onNodeWithStringId(R.string.next)
.performClick()
}
當您測試「開始」畫面以外的畫面時,必須規劃「向上」按鈕功能,確保畫面會導向上一個畫面。請考慮建立 helper 函式,找出「向上」按鈕,然後按一下。
private fun performNavigateUp() {
val backText = composeTestRule.activity.getString(R.string.back_button)
composeTestRule.onNodeWithContentDescription(backText).performClick()
}
盡量提高測試涵蓋範圍
應用程式的測試套件應盡可能測試應用程式功能。在完美世界中,UI 測試套件會涵蓋 100% 的 UI 功能。實際上,由於應用程式外部許多可能影響 UI 的因素,例如具有不同螢幕大小的裝置、不同版本的 Android 作業系統,以及可能會影響手機上其他應用程式的第三方應用程式,所以很難實現大量測試涵蓋範圍。
如要盡可能提高測試涵蓋範圍,其中一種方式是在新增功能時一併撰寫測試。這樣一來,您就能避免過度掌握新功能,也不必反覆記住所有可能的情境。目前,紙杯蛋糕是相當小的應用程式,而您測試了應用程式導覽的一大部分!不過,還有其他要測試的導覽狀態。
確認是否可寫入測試以驗證下列導覽狀態。建議您先自行實作,再查看解決方案。
- 按一下口味螢幕中的「向上」按鈕以前往「開始」螢幕
- 按一下「口味」畫面中的「取消」按鈕,前往「開始」畫面
- 前往取貨畫面
- 按一下「取貨」畫面中的「向上」按鈕,前往「口味」畫面
- 按一下「取貨」畫面中的「取消」按鈕,前往「開始」畫面
- 前往「摘要」畫面
- 按一下「摘要」畫面中的「取消」按鈕,前往「開始」畫面。
@Test
fun cupcakeNavHost_clickNextOnFlavorScreen_navigatesToPickupScreen() {
navigateToFlavorScreen()
composeTestRule.onNodeWithStringId(R.string.next)
.performClick()
navController.assertCurrentRouteName(CupcakeScreen.Pickup.name)
}
@Test
fun cupcakeNavHost_clickBackOnFlavorScreen_navigatesToStartOrderScreen() {
navigateToFlavorScreen()
performNavigateUp()
navController.assertCurrentRouteName(CupcakeScreen.Start.name)
}
@Test
fun cupcakeNavHost_clickCancelOnFlavorScreen_navigatesToStartOrderScreen() {
navigateToFlavorScreen()
composeTestRule.onNodeWithStringId(R.string.cancel)
.performClick()
navController.assertCurrentRouteName(CupcakeScreen.Start.name)
}
@Test
fun cupcakeNavHost_clickNextOnPickupScreen_navigatesToSummaryScreen() {
navigateToPickupScreen()
composeTestRule.onNodeWithText(getFormattedDate())
.performClick()
composeTestRule.onNodeWithStringId(R.string.next)
.performClick()
navController.assertCurrentRouteName(CupcakeScreen.Summary.name)
}
@Test
fun cupcakeNavHost_clickBackOnPickupScreen_navigatesToFlavorScreen() {
navigateToPickupScreen()
performNavigateUp()
navController.assertCurrentRouteName(CupcakeScreen.Flavor.name)
}
@Test
fun cupcakeNavHost_clickCancelOnPickupScreen_navigatesToStartOrderScreen() {
navigateToPickupScreen()
composeTestRule.onNodeWithStringId(R.string.cancel)
.performClick()
navController.assertCurrentRouteName(CupcakeScreen.Start.name)
}
@Test
fun cupcakeNavHost_clickCancelOnSummaryScreen_navigatesToStartOrderScreen() {
navigateToSummaryScreen()
composeTestRule.onNodeWithStringId(R.string.cancel)
.performClick()
navController.assertCurrentRouteName(CupcakeScreen.Start.name)
}
6. 撰寫「訂單」畫面的測試
導覽只是 Cupcake 應用程式的一個方面。使用者與每個應用程式畫面互動。您必須確認這些畫面顯示的內容,並在這些螢幕上執行的動作符合正確的結果。SelectOptionScreen 是應用程式的重要部分。
在本節中,您將撰寫測試,確認這個畫面中的內容設定是否正確。
測試「選擇情境」畫面內容
- 在
app/src/androidTest
目錄中建立名為CupcakeOrderScreenTest
的新類別,在其他測試檔案中已存放。
- 在這個類別中,建立
AndroidComposeTestRule
。
@get:Rule
val composeTestRule = createAndroidComposeRule<ComponentActivity>()
- 建立名為
selectOptionScreen_verifyContent()
的函式,並以@Test
加上註解。
@Test
fun selectOptionScreen_verifyContent() {
}
您會使用這個函式將 Compose 規則內容設為 SelectOptionScreen
。這樣做可確保 SelectOptionScreen
可組合元件直接啟動,因此不需要瀏覽。不過,這個畫面需要兩個參數:小計和口味選項清單。
- 建立口味清單和要傳送至畫面的小計。
@Test
fun selectOptionScreen_verifyContent() {
// Given list of options
val flavours = listOf("Vanilla", "Chocolate", "Hazelnut", "Cookie", "Mango")
// And sub total
val subTotal = "$100"
}
- 使用剛建立的值,將內容設為使用
CupcakeTheme
的SelectOptionScreen
可組合元件。
請注意,這個方法與從 MainActivity
啟動可組合函式類似。唯一的差別在於,MainActivity
會呼叫 CupcakeApp
可組合元件,而此處會呼叫 SelectOptionScreen
可組合元件。透過變更從 setContent()
啟動的可組合元件,您可以啟動特定可組合元件,不必在測試中循序漸進地執行應用程式來前往要測試的區域。這種做法有助於避免在與目前測試無關的程式碼中失敗。
@Test
fun selectOptionScreen_verifyContent() {
// Given list of options
val flavours = listOf("Vanilla", "Chocolate", "Hazelnut", "Cookie", "Mango")
// And sub total
val subTotal = "$100"
// When SelectOptionScreen is loaded
composeTestRule.setContent {
CupcakeTheme {
SelectOptionScreen(subtotal = subTotal, options = flavours)
}
}
}
在測試中,應用程式會啟動 SelectOptionScreen
可組合元件,然後您就可以透過測試操作說明與應用程式互動。
- 透過
flavours
清單疊代,確保清單中的每個字串項目都顯示在畫面上。 - 使用
onNodeWithText()
方法尋找畫面上的文字,並使用assertIsDisplayed()
方法驗證文字是否顯示在應用程式中。
@Test
fun selectOptionScreen_verifyContent() {
// Given list of options
val flavours = listOf("Vanilla", "Chocolate", "Hazelnut", "Cookie", "Mango")
// And sub total
val subTotal = "$100"
// When SelectOptionScreen is loaded
composeTestRule.setContent {
CupcakeTheme {
SelectOptionScreen(subtotal = subTotal, options = flavours)
}
}
// Then all the options are displayed on the screen.
flavours.forEach { flavour ->
composeTestRule.onNodeWithText(flavour).assertIsDisplayed()
}
}
- 使用相同技巧驗證應用程式顯示文字,確認應用程式在螢幕上顯示正確的小計字串。在畫面上搜尋
R.string.subtotal_price
資源 ID 和正確的小計值,然後宣告應用程式會顯示該值。
@Test
fun selectOptionScreen_verifyContent() {
// Given list of options
val flavours = listOf("Vanilla", "Chocolate", "Hazelnut", "Cookie", "Mango")
// And sub total
val subTotal = "$100"
// When SelectOptionScreen is loaded
composeTestRule.setContent {
CupcakeTheme {
SelectOptionScreen(subtotal = subTotal, options = flavours)
}
}
// Then all the options are displayed on the screen.
flavours.forEach { flavour ->
composeTestRule.onNodeWithText(flavour).assertIsDisplayed()
}
// And then the subtotal is displayed correctly.
composeTestRule.onNodeWithText(
composeTestRule.activity.getString(
R.string.subtotal_price,
subTotal
)
).assertIsDisplayed()
}
請注意,你必須先選取項目,系統才會顯示下一步按鈕。這項測試只會驗證畫面內容,因此最後測試的方法是下一步按鈕。
- 使用相同方法尋找按字串資源 ID 尋找節點的下一步按鈕。不過,您可以使用
assertIsNotEnabled()
方法,而不是驗證應用程式顯示節點。
@Test
fun selectOptionScreen_verifyContent() {
// Given list of options
val flavours = listOf("Vanilla", "Chocolate", "Hazelnut", "Cookie", "Mango")
// And sub total
val subTotal = "$100"
// When SelectOptionScreen is loaded
composeTestRule.setContent {
CupcakeTheme {
SelectOptionScreen(subtotal = subTotal, options = flavours)
}
}
// Then all the options are displayed on the screen.
flavours.forEach { flavour ->
composeTestRule.onNodeWithText(flavour).assertIsDisplayed()
}
// And then the subtotal is displayed correctly.
composeTestRule.onNodeWithText(
composeTestRule.activity.getString(
R.string.subtotal_price,
subTotal
)
).assertIsDisplayed()
// And then the next button is disabled
composeTestRule.onNodeWithStringId(R.string.next).assertIsNotEnabled()
}
盡量提高測試涵蓋範圍
「選擇口味」畫面內容測試只能測試單一畫面的某方面。您可以撰寫一些額外的測試來提高程式碼涵蓋率。下載解決方案程式碼前,請先自行撰寫下列測試。
- 驗證「開始」螢幕內容。
- 驗證「摘要」螢幕內容。
- 在「選擇口味」螢幕中選取選項時,確認已啟用下一步按鈕。
撰寫測試時,請留意任何有助於減少程式碼撰寫量的輔助函式。
7. 解決方案程式碼
8. 摘要
恭喜!您已瞭解如何測試 Jetpack 導覽元件。您也會學到撰寫 UI 測試的一些基本技能,例如撰寫可重複使用的 helper方法、如何利用 setContent()
撰寫簡潔測試、透過 @Before
註解設定測試,以及如何思考最高測試涵蓋率。繼續建構 Android 應用程式時,別忘了持續撰寫測試及功能程式碼!