Тест. Создание навигации.

Отделите код навигации от ваших составных элементов, чтобы иметь возможность тестировать каждый составной элемент изолированно, отдельно от составного элемента 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» .