Отделите код навигации от ваших составных элементов, чтобы иметь возможность тестировать каждый составной элемент изолированно, отдельно от составного элемента NavHost .
Не передавайте NavController напрямую в составные компоненты. Вместо этого передавайте в качестве параметров функции обратного вызова навигации (лямбда-выражения). Это позволит тестировать все ваши составные компоненты по отдельности, поскольку в тестах им не требуется экземпляр NavController .
composable лямбда-функция в вашем NavHost выступает в качестве моста между 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 , добавьте следующую зависимость navigation-testing в файл 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> { /*...*/ }
}
}
Теперь вы можете протестировать AppNavHost и логику навигации, определенную внутри NavHost , передав экземпляр артефакта для тестирования навигации TestNavHostController .
Тест пользовательского интерфейса, проверяющий начальный пункт назначения вашего приложения и NavHost , будет выглядеть следующим образом:
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()
}
}
Проверьте действия навигации.
Проверить реализацию навигации можно несколькими способами: кликая по элементам пользовательского интерфейса и затем либо проверяя отображаемый пункт назначения, либо сравнивая ожидаемый маршрут с текущим.
Поскольку вы хотите протестировать реализацию вашего конкретного приложения, предпочтительнее использовать клики по элементам пользовательского интерфейса. Чтобы узнать, как тестировать это вместе с отдельными составными функциями в отрыве от контекста, см. практическое руководство по тестированию в Jetpack Compose .
Также вы можете использовать navController для проверки корректности навигации, сравнивая текущий маршрут с ожидаемым, используя currentBackStackEntry :
@Test
fun appNavHost_clickProfile_navigatesToProfile() {
composeTestRule.onNodeWithContentDescription("Go to Profile")
.performClick()
assertTrue(navController.currentBackStackEntry?.destination?.hasRoute<Profile>() ?: false)
}
Дополнительные рекомендации по основам тестирования Compose см. в руководстве «Тестирование макета Compose» .