Esistono tre modi principali per interagire con gli elementi dell'interfaccia utente:
- I rilevatori ti consentono di selezionare uno o più elementi (o nodi nell'albero della semantica) per creare asserzioni o eseguire azioni su questi elementi.
- Le asserzioni vengono utilizzate per verificare che gli elementi esistano o abbiano determinati 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 uno o più
nodi nell'albero della semantica.
Ricercatori
Puoi utilizzare onNode
e onAllNodes
per selezionare rispettivamente uno o più nodi, ma puoi anche utilizzare strumenti di ricerca di convenienza per le ricerche più comuni, ad esempio onNodeWithText
e onNodeWithContentDescription
. Puoi sfogliare l'elenco completo nella
scheda di riferimento per il test di Compose.
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 pulsante 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 visualizza il seguente output:
Node #1 at (...)px
|-Node #2 at (...)px
Role = 'Button'
Text = '[Hello, World]'
Actions = [OnClick, GetTextLayoutResult]
MergeDescendants = 'true'
Se devi trovare una corrispondenza con un nodo di quello che sarebbe l'albero non unito, puoi impostare useUnmergedTree
su true
:
composeTestRule.onRoot(useUnmergedTree = true).printToLog("TAG")
Questo codice stampa 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 finder. Ad esempio, qui viene utilizzato in un cercatore di onNodeWithText
.
composeTestRule
.onNodeWithText("World", useUnmergedTree = true).assertIsDisplayed()
Affermazioni
Controlla le asserzioni chiamando assert()
sul SemanticsNodeInteraction
restituito da un cercatore con uno o più corrispondenti:
// 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 sfogliare l'elenco completo nel cheat sheet di Compose Testing.
Esistono anche funzioni per controllare le asserzioni su una raccolta 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()
Ecco alcuni esempi di azioni:
performClick(),
performSemanticsAction(key),
performKeyPress(keyEvent),
performGesture { swipeLeft() }
Puoi sfogliare l'elenco completo nel cheat sheet di Compose Testing.
Confrontatori
Esistono diversi corrispondenti disponibili per testare il codice Compose.
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 corrispondenti:
composeTestRule.onNode(hasParent(hasText("Button")))
.assertIsDisplayed()
Selettori
Un modo alternativo per creare test è utilizzare i selettori, che possono rendere alcuni test più leggibili.
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 con strumenti: è buona prassi eseguire anche test con strumenti. ovvero i test eseguiti direttamente sul dispositivo.
- Integrazione continua: l'integrazione continua ti consente di integrare i test nella pipeline di deployment.
- Prova schermi di dimensioni diverse: con alcuni dispositivi a disposizione degli utenti, ti conviene eseguire test per schermi di dimensioni diverse.
- Espresso: sebbene sia destinato alle UI basate su visualizzazioni, le conoscenze di Espresso possono essere utili per alcuni aspetti dei test di Compose.