API de prueba

Hay 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 un 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 de conveniencia para las búsquedas más comunes, como onNodeWithText y onNodeWithContentDescription. Puedes explorar 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 estos:

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 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 de conveniencia para las aserciones más comunes, como assertExists, assertIsDisplayed y assertTextEquals. Puedes explorar 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 buscar coincidencias.

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 explorar 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 conceptos 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 apps para Android.
  • Pruebas locales: Puedes ejecutar algunas pruebas de forma local en tu propia estación de trabajo.
  • Pruebas instrumentadas: se recomienda ejecutar también pruebas de instrumentación. 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 algunos dispositivos disponibles para los usuarios, debes probar diferentes tamaños de pantalla.
  • Espresso: Si bien está diseñado para las IU basadas en View, el conocimiento de Espresso puede ser útil para algunos aspectos de las pruebas de Compose.