Existen tres formas principales de interactuar con los elementos de la IU:
- Los buscadores te permiten seleccionar uno o varios elementos (o nodos en el árbol semántico) para realizar aserciones o acciones sobre ellos.
- Las aserciones se usan para verificar que los elementos existan o tengan determinados atributos.
- Las acciones insertan eventos simulados del usuario en los elementos, como clics u otros gestos.
Algunas de estas APIs aceptan SemanticsMatcher
para hacer referencia a uno o más nodos en el árbol semántico.
Buscadores
Puedes usar onNode
y onAllNodes
para seleccionar uno o varios nodos, respectivamente, pero también puedes usar buscadores prácticos para las búsquedas más comunes, como onNodeWithText
y onNodeWithContentDescription
. Puedes consultar la lista completa en la hoja de referencia para pruebas de Compose.
Seleccionar un solo nodo
composeTestRule.onNode(<<SemanticsMatcher>>, useUnmergedTree = false): SemanticsNodeInteraction
// Example
composeTestRule
.onNode(hasText("Button")) // Equivalent to onNodeWithText("Button")
Para seleccionar varios nodos
composeTestRule
.onAllNodes(<<SemanticsMatcher>>): SemanticsNodeInteractionCollection
// Example
composeTestRule
.onAllNodes(hasText("Button")) // Equivalent to onAllNodesWithText("Button")
Árbol separado
Algunos nodos combinan la información semántica de sus elementos secundarios. Por ejemplo, un botón con dos elementos de texto combina las etiquetas de los elementos de texto:
MyButton {
Text("Hello")
Text("World")
}
En una prueba, usa printToLog()
para mostrar el árbol semántico:
composeTestRule.onRoot().printToLog("TAG")
Este código muestra el siguiente resultado:
Node #1 at (...)px
|-Node #2 at (...)px
Role = 'Button'
Text = '[Hello, World]'
Actions = [OnClick, GetTextLayoutResult]
MergeDescendants = 'true'
Si necesitas vincular un nodo de lo que sería el árbol separado, puedes configurar useUnmergedTree
como true
:
composeTestRule.onRoot(useUnmergedTree = true).printToLog("TAG")
Este código muestra el siguiente resultado:
Node #1 at (...)px
|-Node #2 at (...)px
OnClick = '...'
MergeDescendants = 'true'
|-Node #3 at (...)px
| Text = '[Hello]'
|-Node #5 at (83.0, 86.0, 191.0, 135.0)px
Text = '[World]'
El parámetro useUnmergedTree
está disponible en todos los buscadores. Por ejemplo, aquí se usa en un buscador onNodeWithText
.
composeTestRule
.onNodeWithText("World", useUnmergedTree = true).assertIsDisplayed()
Aserciones
Para verificar las aserciones, llama a assert()
en el objeto SemanticsNodeInteraction
que muestra un buscador con uno o varios comparadores:
// Single matcher:
composeTestRule
.onNode(matcher)
.assert(hasText("Button")) // hasText is a SemanticsMatcher
// Multiple matchers can use and / or
composeTestRule
.onNode(matcher).assert(hasText("Button") or hasText("Button2"))
También puedes usar funciones prácticas para las aserciones más frecuentes, como assertExists
, assertIsDisplayed
y assertTextEquals
.
Puedes consultar la lista completa en la hoja de referencia para pruebas de Compose.
También existen funciones para verificar aserciones en una colección de nodos:
// Check number of matched nodes
composeTestRule
.onAllNodesWithContentDescription("Beatle").assertCountEquals(4)
// At least one matches
composeTestRule
.onAllNodesWithContentDescription("Beatle").assertAny(hasTestTag("Drummer"))
// All of them match
composeTestRule
.onAllNodesWithContentDescription("Beatle").assertAll(hasClickAction())
Acciones
Para insertar una acción en un nodo, llama a una función perform…()
:
composeTestRule.onNode(...).performClick()
Estos son algunos ejemplos de acciones:
performClick(),
performSemanticsAction(key),
performKeyPress(keyEvent),
performGesture { swipeLeft() }
Puedes consultar la lista completa en la hoja de referencia para pruebas de Compose.
Comparadores
Hay una variedad de comparadores disponibles para probar tu código de Compose.
Comparadores jerárquicos
Los comparadores jerárquicos te permiten subir o bajar por el árbol semántico, y realizar vinculaciones.
fun hasParent(matcher: SemanticsMatcher): SemanticsMatcher
fun hasAnySibling(matcher: SemanticsMatcher): SemanticsMatcher
fun hasAnyAncestor(matcher: SemanticsMatcher): SemanticsMatcher
fun hasAnyDescendant(matcher: SemanticsMatcher): SemanticsMatcher
Estos son algunos ejemplos de cómo se usan esos comparadores:
composeTestRule.onNode(hasParent(hasText("Button")))
.assertIsDisplayed()
Selectores
Otra forma de crear pruebas es usar selectores, que pueden hacer que algunas pruebas sean más legibles.
composeTestRule.onNode(hasTestTag("Players"))
.onChildren()
.filter(hasClickAction())
.assertCountEquals(4)
.onFirst()
.assert(hasText("John"))
Puedes consultar la lista completa en la hoja de referencia para pruebas de Compose.
Recursos adicionales
- Cómo probar apps en Android: La página de destino principal de pruebas de Android proporciona una vista más amplia de los aspectos básicos y las técnicas de prueba.
- Aspectos básicos de las pruebas: Obtén más información sobre los conceptos básicos de las pruebas de una app para Android.
- Pruebas locales: Puedes ejecutar algunas pruebas de forma local, en tu propia estación de trabajo.
- Pruebas instrumentadas: Se recomienda ejecutar pruebas instrumentadas. Es decir, pruebas que se ejecutan directamente en el dispositivo.
- Integración continua: La integración continua te permite integrar tus pruebas en la canalización de implementación.
- Prueba diferentes tamaños de pantalla: Con muchos dispositivos disponibles para los usuarios, debes probar diferentes tamaños de pantalla.
- Espresso: Si bien está diseñado para IUs basadas en objetos View, el conocimiento de Espresso puede ser útil para algunos aspectos de las pruebas de Compose.