Es gibt drei Möglichkeiten, mit UI-Elementen zu interagieren:
- Mit Findern können Sie ein oder mehrere Elemente (oder Knoten im semantischen Baum) auswählen, um Behauptungen zu ihnen aufzustellen oder Aktionen für sie auszuführen.
- Mit Assertions wird geprüft, ob die Elemente vorhanden sind oder bestimmte Attribute haben.
- Mit Aktionen werden simulierte Nutzerereignisse wie Klicks oder andere Gesten in die Elemente eingefügt.
Einige dieser APIs akzeptieren ein SemanticsMatcher
, um auf einen oder mehrere Knoten im semantischen Baum zu verweisen.
Finder
Sie können onNode
und onAllNodes
verwenden, um einen oder mehrere Knoten auszuwählen. Sie können aber auch praktische Suchfunktionen für die häufigsten Suchvorgänge verwenden, z. B. onNodeWithText
und onNodeWithContentDescription
. Die vollständige Liste finden Sie im Compose-Test-Spickzettel.
Einzelnen Knoten auswählen
composeTestRule.onNode(<<SemanticsMatcher>>, useUnmergedTree = false): SemanticsNodeInteraction
// Example
composeTestRule
.onNode(hasText("Button")) // Equivalent to onNodeWithText("Button")
Mehrere Knoten auswählen
composeTestRule
.onAllNodes(<<SemanticsMatcher>>): SemanticsNodeInteractionCollection
// Example
composeTestRule
.onAllNodes(hasText("Button")) // Equivalent to onAllNodesWithText("Button")
Nicht zusammengeführter Baum
Bei einigen Knoten werden die Semantikinformationen ihrer untergeordneten Elemente zusammengeführt. Wenn eine Schaltfläche beispielsweise zwei Textelemente enthält, werden die Labels der Textelemente zusammengeführt:
MyButton {
Text("Hello")
Text("World")
}
Verwenden Sie in einem Test printToLog()
, um den Semantikbaum anzuzeigen:
composeTestRule.onRoot().printToLog("TAG")
Dieser Code gibt Folgendes aus:
Node #1 at (...)px
|-Node #2 at (...)px
Role = 'Button'
Text = '[Hello, World]'
Actions = [OnClick, GetTextLayoutResult]
MergeDescendants = 'true'
Wenn Sie einen Knoten des nicht zusammengeführten-Baums abgleichen müssen, können Sie useUnmergedTree
auf true
festlegen:
composeTestRule.onRoot(useUnmergedTree = true).printToLog("TAG")
Dieser Code gibt Folgendes aus:
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]'
Der Parameter useUnmergedTree
ist in allen Findern verfügbar. Hier wird sie beispielsweise in einem onNodeWithText
-Finder verwendet.
composeTestRule
.onNodeWithText("World", useUnmergedTree = true).assertIsDisplayed()
Assertions
Prüfen Sie Zusicherungen, indem Sie assert()
für die SemanticsNodeInteraction
aufrufen, die von einem Finder mit einem oder mehreren Matchern zurückgegeben wird:
// 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"))
Sie können auch Convenience-Funktionen für die häufigsten Zusicherungen verwenden, z. B. assertExists
, assertIsDisplayed
und assertTextEquals
.
Die vollständige Liste finden Sie im Compose-Test-Spickzettel.
Es gibt auch Funktionen zum Prüfen von Zusicherungen für eine Sammlung von Knoten:
// 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())
Aktionen
Wenn Sie einem Knoten eine Aktion hinzufügen möchten, rufen Sie eine perform…()
-Funktion auf:
composeTestRule.onNode(...).performClick()
Hier einige Beispiele für Aktionen:
performClick(),
performSemanticsAction(key),
performKeyPress(keyEvent),
performGesture { swipeLeft() }
Die vollständige Liste finden Sie im Compose-Test-Spickzettel.
Matcher
Für das Testen Ihres Compose-Codes stehen verschiedene Matcher zur Verfügung.
Hierarchische Matcher
Mit hierarchischen Matchern können Sie im semantischen Baum nach oben oder unten gehen und Abgleiche durchführen.
fun hasParent(matcher: SemanticsMatcher): SemanticsMatcher
fun hasAnySibling(matcher: SemanticsMatcher): SemanticsMatcher
fun hasAnyAncestor(matcher: SemanticsMatcher): SemanticsMatcher
fun hasAnyDescendant(matcher: SemanticsMatcher): SemanticsMatcher
Hier einige Beispiele für die Verwendung dieser Abgleichstypen:
composeTestRule.onNode(hasParent(hasText("Button")))
.assertIsDisplayed()
Selektoren
Eine alternative Möglichkeit zum Erstellen von Tests ist die Verwendung von Selektoren, die einige Tests lesbarer machen können.
composeTestRule.onNode(hasTestTag("Players"))
.onChildren()
.filter(hasClickAction())
.assertCountEquals(4)
.onFirst()
.assert(hasText("John"))
Die vollständige Liste finden Sie im Compose-Test-Spickzettel.
Zusätzliche Ressourcen
- Apps unter Android testen: Auf der Haupt-Landingpage für Android-Tests finden Sie einen umfassenderen Überblick über die Grundlagen und Techniken des Testens.
- Grundlagen des Testens:Hier finden Sie weitere Informationen zu den grundlegenden Konzepten für das Testen einer Android-App.
- Lokale Tests:Einige Tests können lokal auf Ihrer Workstation ausgeführt werden.
- Instrumentierte Tests:Es empfiehlt sich, auch instrumentierte Tests auszuführen. Das sind Tests, die direkt auf dem Gerät ausgeführt werden.
- Continuous Integration:Mit Continuous Integration können Sie Ihre Tests in Ihre Bereitstellungspipeline einbinden.
- Verschiedene Bildschirmgrößen testen:Da Nutzer viele verschiedene Geräte verwenden können, sollten Sie verschiedene Bildschirmgrößen testen.
- Espresso: Obwohl Espresso für ansichtsbasierte UIs gedacht ist, kann es für einige Aspekte von Compose-Tests hilfreich sein.