APIs testen

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.