Esistono tre modi principali per interagire con gli elementi dell'interfaccia utente:
- I ricercatori ti consentono di selezionare uno o più elementi (o nodi nella struttura ad albero della semantica) per fare affermazioni o eseguire azioni su di essi.
- Le asserzioni vengono utilizzate per verificare che gli elementi esistano o abbiano determinate attributi.
- Le azioni iniettano eventi utente simulati negli elementi, ad esempio clic o altri gesti.
Alcune di queste API accettano un SemanticsMatcher
per fare riferimento a una o più
nodi nell'albero della semantica.
Ricercatori
Puoi utilizzare onNode
e onAllNodes
per selezionare uno o più nodi
ma puoi anche usare gli strumenti di ricerca di convenienza per le
come onNodeWithText
, e
onNodeWithContentDescription
. Puoi sfogliare l'elenco completo nel
cheat sheet di Compose Testing.
Seleziona un singolo nodo
composeTestRule.onNode(<<SemanticsMatcher>>, useUnmergedTree = false): SemanticsNodeInteraction
// Example
composeTestRule
.onNode(hasText("Button")) // Equivalent to onNodeWithText("Button")
Seleziona più nodi
composeTestRule
.onAllNodes(<<SemanticsMatcher>>): SemanticsNodeInteractionCollection
// Example
composeTestRule
.onAllNodes(hasText("Button")) // Equivalent to onAllNodesWithText("Button")
Albero non unito
Alcuni nodi uniscono le informazioni semantiche dei relativi figli. Ad esempio, un con due elementi di testo unisce le etichette degli elementi di testo:
MyButton {
Text("Hello")
Text("World")
}
Da un test, utilizza printToLog()
per visualizzare l'albero della semantica:
composeTestRule.onRoot().printToLog("TAG")
Questo codice stampa il seguente output:
Node #1 at (...)px
|-Node #2 at (...)px
Role = 'Button'
Text = '[Hello, World]'
Actions = [OnClick, GetTextLayoutResult]
MergeDescendants = 'true'
Per trovare una corrispondenza con un nodo di quello che sarebbe l'albero non unito, puoi impostare
Da useUnmergedTree
a true
:
composeTestRule.onRoot(useUnmergedTree = true).printToLog("TAG")
Questo codice visualizza il seguente output:
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]'
Il parametro useUnmergedTree
è disponibile in tutti i risultati di ricerca. Ad esempio, qui
viene utilizzata in un cercatore onNodeWithText
.
composeTestRule
.onNodeWithText("World", useUnmergedTree = true).assertIsDisplayed()
Asserzioni
Verifica le asserzioni chiamando assert()
su SemanticsNodeInteraction
restituiti da un cercatore con uno o più matcher:
// 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"))
Puoi anche utilizzare funzioni di utilità per le asserzioni più comuni, ad esempio
assertExists
, assertIsDisplayed
e assertTextEquals
.
Puoi consultare l'elenco completo nella scheda di riferimento del test di Compose.
Esistono anche funzioni per verificare le asserzioni su un insieme di nodi:
// 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())
Azioni
Per iniettare un'azione in un nodo, chiama una funzione perform…()
:
composeTestRule.onNode(...).performClick()
Di seguito sono riportati alcuni esempi di azioni:
performClick(),
performSemanticsAction(key),
performKeyPress(keyEvent),
performGesture { swipeLeft() }
Puoi sfogliare l'elenco completo nel cheat sheet di Compose Testing.
Corrispondenza
Per testare il codice Compose sono disponibili diversi corrispondenti.
Matcher gerarchici
I corrispondenti gerarchici ti consentono di spostarti verso l'alto o verso il basso nella struttura ad albero della semantica ed eseguire la corrispondenza.
fun hasParent(matcher: SemanticsMatcher): SemanticsMatcher
fun hasAnySibling(matcher: SemanticsMatcher): SemanticsMatcher
fun hasAnyAncestor(matcher: SemanticsMatcher): SemanticsMatcher
fun hasAnyDescendant(matcher: SemanticsMatcher): SemanticsMatcher
Ecco alcuni esempi di utilizzo di questi matcher:
composeTestRule.onNode(hasParent(hasText("Button")))
.assertIsDisplayed()
Selettori
Un modo alternativo per creare test è utilizzare selettori che possono rendere per rendere più leggibili i test.
composeTestRule.onNode(hasTestTag("Players"))
.onChildren()
.filter(hasClickAction())
.assertCountEquals(4)
.onFirst()
.assert(hasText("John"))
Puoi sfogliare l'elenco completo nel cheat sheet di Compose Testing.
Risorse aggiuntive
- Testare le app su Android: la pagina di destinazione principale per i test su Android offre una visione più ampia delle nozioni di base e delle tecniche di test.
- Nozioni di base sui test: scopri di più sui concetti fondamentali alla base del test di un'app per Android.
- Test locali: puoi eseguire alcuni test localmente, sulla tua workstation.
- Test strumentati: va bene di eseguire anche test strumentati. ovvero test eseguiti direttamente sul dispositivo.
- Integrazione continua: l'integrazione continua ti consente di integrare i test nella pipeline di deployment.
- Esegui test su diverse dimensioni dello schermo: con così tanti dispositivi a disposizione degli utenti, devi testare diverse dimensioni dello schermo.
- Espresso: sebbene sia destinato alle UI basate su visualizzazioni, le conoscenze di Espresso possono essere utili per alcuni aspetti dei test di Compose.