O Compose se integra a frameworks de teste comuns.
Interoperabilidade com o Espresso
Em um app híbrido, é possível encontrar componentes do Compose dentro de hierarquias de visualização e
visualizações dentro dos elementos do Compose (com o elemento combinável AndroidView).
Não há etapas específicas que sejam necessárias para fazer correspondência a nenhum dos tipos. A correspondência de visualizações é feita usando o método
onView do Espresso e os elementos do Compose com ComposeTestRule.
@Test
fun androidViewInteropTest() {
// Check the initial state of a TextView that depends on a Compose state.
Espresso.onView(withText("Hello Views")).check(matches(isDisplayed()))
// Click on the Compose button that changes the state.
composeTestRule.onNodeWithText("Click here").performClick()
// Check the new value.
Espresso.onView(withText("Hello Compose")).check(matches(isDisplayed()))
}
Adicionar semântica no escopo da visualização para testes de interoperabilidade do Compose
Limitar pesquisas do Compose a visualizações específicas
Ao migrar interfaces complexas para o Compose, você pode encontrar elementos
iguais do Compose aninhados em várias visualizações tradicionais do Android, como em um
RecyclerView ou um ViewPager. Nesses cenários, uma pesquisa padrão do Compose
como onNodeWithText("Save") pode falhar com um erro "Vários nós encontrados".
Em vez de modificar o código de produção para injetar tags de teste dinâmicas e distinguir esses elementos, você pode restringir o teste do Compose diretamente a uma visualização específica do Android.
Use a API onRootWithViewInteraction na sua regra de teste. Essa função aceita
um ViewInteraction do Espresso, permitindo que você use o Espresso para isolar uma
View de contêiner específica e realizar interações do Compose exclusivamente dentro
dessa hierarquia com escopo.
Interagir com um item da lista
Se você precisar interagir com um elemento do Compose em uma linha RecyclerView
específica, use o Espresso para localizar a linha e, em seguida, defina o escopo da interação do Compose para ela.
Isso ignora elementos idênticos do Compose em todas as outras linhas.
@Test fun testComposeButtonInsideRecyclerViewItem() = runComposeUiTest { // Scroll to the desired position using Espresso Espresso.onView(withId(recyclerViewId)) .perform(RecyclerViewActions.scrollToPosition<MyViewHolder>(3)) // Define an Espresso ViewInteraction that uniquely identifies the row val rowView = Espresso.onView( allOf( withId(rootViewId), hasDescendant(withText("Item #3")) ) ) // Scope the Compose search strictly to that specific row View onRootWithViewInteraction(rowView) .onNode(hasText("Like")) .performClick() }
Resolver ambiguidade em ViewPagers
Quando vários fragmentos com layouts do Compose idênticos estão na memória simultaneamente, você pode restringir a pesquisa ao ID da visualização raiz do fragmento específico para evitar ambiguidade de correspondência.
@Test fun testComposeButtonInsideViewPagerItem() = runComposeUiTest { // Swipe to the desired page using Espresso Espresso.onView(withId(viewPagerViewId)).perform(swipeLeft()) // Identify the specific container view using Espresso val fragmentB = Espresso.onView(withId(fragmentRootViewId)) // The generic text "Save" is now unique within this view scope onRootWithViewInteraction(fragmentB) .onNode(hasText("Save")) .assertIsDisplayed() }
Interoperabilidade com o UiAutomator
Por padrão, os elementos combináveis podem ser acessados no UiAutomator apenas pelos
descritores convenientes (texto mostrado, descrição do conteúdo etc.). Caso queira
acessar um elemento combinável que use Modifier.testTag, é necessário ativar
a propriedade semântica testTagsAsResourceId para a subárvore
do elemento combinável específico. Ativar esse comportamento é útil para elementos combináveis que não têm nenhum outro
elemento exclusivo, por exemplo, elementos roláveis como a LazyColumn.
Ative a propriedade semântica apenas uma vez na hierarquia dos elementos combináveis para
garantir que todos os elementos combináveis aninhados com Modifier.testTag possam ser acessados pelo
UiAutomator.
Scaffold(
// Enables for all composables in the hierarchy.
modifier = Modifier.semantics {
testTagsAsResourceId = true
}
){
// Modifier.testTag is accessible from UiAutomator for composables nested here.
LazyColumn(
modifier = Modifier.testTag("myLazyColumn")
){
// Content
}
}
Todos os elementos combináveis com Modifier.testTag(tag) podem ser acessados com
By.res(resourceName) usando a mesma tag do resourceName.
val device = UiDevice.getInstance(getInstrumentation())
val lazyColumn: UiObject2 = device.findObject(By.res("myLazyColumn"))
// Some interaction with the lazyColumn.
Outros recursos
- Testar apps no Android: a página de destino principal de testes do Android oferece uma visão mais ampla dos princípios básicos e das técnicas de teste.
- Conceitos básicos de testes:saiba mais sobre os principais conceitos por trás do teste de um app Android.
- Testes locais:é possível executar alguns testes localmente, na sua própria estação de trabalho.
- Testes instrumentados:é uma boa prática executar também testes instrumentados. Ou seja, testes executados diretamente no dispositivo.
- Integração contínua:permite integrar seus testes ao pipeline de implantação.
- Teste diferentes tamanhos de tela:com tantos dispositivos disponíveis para os usuários, é importante testar diferentes tamanhos de tela.
- Espresso: embora seja destinado a interfaces baseadas em visualização, o conhecimento do Espresso ainda pode ser útil para alguns aspectos dos testes do Compose.