Desassocie o código de navegação dos destinos combináveis para permitir o teste
de cada elemento combinável isoladamente, separado do elemento NavHost.
Não transmita o NavController diretamente para nenhum elemento combinável. Em vez disso, transmita
callbacks de navegação (lambdas) como parâmetros. Isso permite que todos os elementos combináveis
sejam testáveis individualmente, já que não exigem uma instância de
NavController em testes.
A lambda composable no NavHost atua como uma ponte entre as
APIs de navegação e o elemento combinável:
@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))
}
}
Dessa forma, ProfileScreen pode ser testado de forma independente da navegação transmitindo
valores e callbacks simulados.
É recomendável programar testes que atendam aos requisitos de navegação do seu app
testando o NavHost, as ações de navegação transmitidas para os elementos e as telas individuais de composição.
Testar o NavHost
Para começar a testar seu NavHost, adicione a seguinte dependência de testes de navegação ao arquivo build.gradle do módulo do app:
dependencies {
androidTestImplementation "androidx.navigation:navigation-testing:$navigationVersion"
}
Encapsule o NavHost do app em um elemento combinável que aceita um
NavHostController como parâmetro:
@Composable
fun AppNavHost(navController: NavHostController){
NavHost(navController = navController, startDestination = Home){
composable<Home> { /*...*/ }
composable<Profile> { /*...*/ }
}
}
Agora é possível testar AppNavHost e a lógica de navegação definida em NavHost
transmitindo uma instância do artefato de teste de navegação
TestNavHostController.
Um teste de UI que verifica o destino inicial do app e NavHost teria esta aparência:
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()
}
}
Testar ações de navegação
Você pode testar a implementação da navegação de várias maneiras. Para isso, clique nos elementos da interface e confira o destino mostrado ou compare a rota esperada com a rota exibida.
Como o objetivo é testar a implementação concreta do app, recomendamos optar por cliques na IU. Para aprender a testar isso de forma isolada com funções de composição individuais, consulte o codelab Como testar no Jetpack Compose.
Também é possível usar o navController para verificar declarações de navegação comparando
a rota atual com a esperada, usando o currentBackStackEntry:
@Test
fun appNavHost_clickProfile_navigatesToProfile() {
composeTestRule.onNodeWithContentDescription("Go to Profile")
.performClick()
assertTrue(navController.currentBackStackEntry?.destination?.hasRoute<Profile>() ?: false)
}
Para mais orientações sobre os conceitos básicos de testes no Compose, consulte o guia Como testar o layout do Compose.