將導覽程式碼與可組合目的地分離,以便分別測試每個可組合項,與 NavHost 可組合項分開。
請勿將 NavController 直接傳遞給任何可組合函式。請改為將導覽回呼 (lambda) 做為參數傳遞。這樣一來,您的所有可組合項都能獨立測試,因為這類測試不需要 NavController 的執行個體。
NavHost 中的 composable lambda 可做為 Navigation API 與可組合項之間的橋樑:
@Composable
fun ProfileScreen(
userId: String,
navigateToFriendProfile: (friendUserId: String) -> Unit
) {
// …
}
// In your NavHost
composable<Profile> { backStackEntry ->
val profile = backStackEntry.toRoute<Profile>()
ProfileScreen(userId = profile.id) { friendUserId ->
navController.navigate(route = Profile(id = friendUserId))
}
}
這樣一來,您就能傳遞模擬值和回呼,獨立測試 ProfileScreen,不必使用 Navigation。
建議您編寫涵蓋應用程式導覽要求的測試,測試 NavHost 時,導覽動作會傳遞至可組合項及個別畫面的可組合項。
測試 NavHost
如要開始測試 NavHost,請在應用程式模組的 build.gradle 檔案中新增下列導覽測試依附元件:
dependencies {
androidTestImplementation "androidx.navigation:navigation-testing:$navigationVersion"
}
將應用程式的 NavHost 包裝在可組合函式中,該函式會接受 NavHostController 做為參數:
@Composable
fun AppNavHost(navController: NavHostController){
NavHost(navController = navController, startDestination = Home){
composable<Home> { /*...*/ }
composable<Profile> { /*...*/ }
}
}
現在,您可以傳遞導覽測試構件 TestNavHostController 的執行個體,測試 AppNavHost 和 NavHost 內定義的導覽邏輯。
用於驗證應用程式起始目的地和 NavHost 的 UI 測試如下所示:
class NavigationTest {
@get:Rule
val composeTestRule = createComposeRule()
lateinit var navController: TestNavHostController
@Before
fun setupAppNavHost() {
composeTestRule.setContent {
navController = TestNavHostController(LocalContext.current)
navController.navigatorProvider.addNavigator(ComposeNavigator())
AppNavHost(navController = navController)
}
}
@Test
fun appNavHost_verifyStartDestination() {
composeTestRule
.onNodeWithContentDescription("Start Screen")
.assertIsDisplayed()
}
}
測試導覽動作
您可以透過多種方式來測試導覽的實作情形,具體方法如下:點按 UI 元素,然後驗證顯示的目的地,或比較預期路徑和目前路徑。
如要測試導入應用程式,建議您按一下使用者介面。如要瞭解如何獨立測試個別可組合函式,請參閱「在 Jetpack Compose 中進行測試」程式碼研究室。
您也可以使用 navController 的 currentBackStackEntry,比較目前路徑與預期路徑,藉此檢查導覽斷言:
@Test
fun appNavHost_clickProfile_navigatesToProfile() {
composeTestRule.onNodeWithContentDescription("Go to Profile")
.performClick()
assertTrue(navController.currentBackStackEntry?.destination?.hasRoute<Profile>() ?: false)
}
如要進一步瞭解 Compose 的測試基本概念,請參閱「測試 Compose 版面配置」指南。