Esistono tre modi principali per interagire con gli elementi della UI:
- I Finder ti consentono di selezionare uno o più elementi (o nodi nell'albero semantico) per fare asserzioni o eseguire azioni.
- Le asserzioni vengono utilizzate per verificare che gli elementi esistano o abbiano determinati attributi.
- Le azioni inseriscono eventi utente simulati sugli elementi, ad esempio clic o altri gesti.
Alcune di queste API accettano un SemanticsMatcher
per fare riferimento a uno o più
nodi nell'albero semantico.
Finder
Puoi utilizzare onNode
e onAllNodes
per selezionare uno o più nodi rispettivamente, ma puoi anche utilizzare i pratici strumenti di ricerca per le ricerche più comuni, ad esempio onNodeWithText
e onNodeWithContentDescription
. Puoi sfogliare l'elenco completo nella
Guida rapida per i test di Compose.
Seleziona un singolo nodo
composeTestRule.onNode(<<SemanticsMatcher>>, useUnmergedTree = false): SemanticsNodeInteraction
// Example
composeTestRule
.onNode(hasText("Button")) // Equivalent to onNodeWithText("Button")
Selezionare 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 nodi secondari. 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 mostrare l'albero semantico:
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'
Se devi trovare la 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()
Asserzioni
Controlla le asserzioni chiamando assert()
su SemanticsNodeInteraction
restituito da un finder 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 convenienza per le asserzioni più comuni, ad esempio
assertExists
, assertIsDisplayed
e assertTextEquals
.
Puoi sfogliare l'elenco completo nella Guida rapida per i test di Compose.
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 inserire 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 nella Guida rapida per i test di Compose.
Matcher
Per testare il codice Compose è disponibile una serie di matcher.
Matcher gerarchici
I matcher gerarchici ti consentono di spostarti verso l'alto o verso il basso nell'albero semantico 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 selettori:
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 nella Guida rapida per i test di Compose.
Risorse aggiuntive
- Testare le app su Android: la pagina di destinazione principale dei test Android offre una visione più ampia dei fondamenti 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: è buona norma eseguire anche test strumentati. ovvero test eseguiti direttamente sul dispositivo.
- Integrazione continua: L'integrazione continua consente di integrare i test nella pipeline di deployment.
- Testa diverse dimensioni dello schermo: con tanti dispositivi a disposizione degli utenti, devi eseguire test per diverse dimensioni dello schermo.
- Espresso: sebbene sia destinato alle UI basate sulla visualizzazione, la conoscenza di Espresso può comunque essere utile per alcuni aspetti dei test di Compose.