テスト API

UI 要素を操作するには、主に次の 3 つの方法があります。

  • ファインダーを使用すると、1 つまたは複数の要素(またはノード)を セマンティクス ツリーなど)が作成されます。
  • アサーションにより、要素が存在することや特定の属性を持つことを確認する。
  • アクションにより、要素に対するクリックやジェスチャーなどのユーザー イベントをシミュレートする。

これらの API のいくつかは、SemanticsMatcher を使用して 1 つ以上の セマンティクス ツリーのノード

ファインダー

onNodeonAllNodes を使用して 1 つ以上のノードを選択できます。 一般的な検索テーマにはコンビニエンス ファインダーを 検索(onNodeWithText など) onNodeWithContentDescription。リスト全体については、 Compose テストのクイック リファレンス

ノードを 1 つ選択する

composeTestRule.onNode(<<SemanticsMatcher>>, useUnmergedTree = false): SemanticsNodeInteraction
// Example
composeTestRule
    .onNode(hasText("Button")) // Equivalent to onNodeWithText("Button")

ノードを複数選択する

composeTestRule
    .onAllNodes(<<SemanticsMatcher>>): SemanticsNodeInteractionCollection
// Example
composeTestRule
    .onAllNodes(hasText("Button")) // Equivalent to onAllNodesWithText("Button")

マージされていないツリー

一部のノードでは、子のセマンティクス情報がマージされます。たとえば、 2 つのテキスト要素を含むボタンをクリックすると、テキスト要素のラベルが結合されます。

MyButton {
    Text("Hello")
    Text("World")
}

テストから、printToLog() を使用してセマンティクス ツリーを表示します。

composeTestRule.onRoot().printToLog("TAG")

このコードでは、次の出力が表示されます。

Node #1 at (...)px
 |-Node #2 at (...)px
   Role = 'Button'
   Text = '[Hello, World]'
   Actions = [OnClick, GetTextLayoutResult]
   MergeDescendants = 'true'

マージされていないツリーのノードと一致させる必要がある場合は、useUnmergedTreetrue に設定します。

composeTestRule.onRoot(useUnmergedTree = true).printToLog("TAG")

このコードでは、次の出力が表示されます。

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]'

useUnmergedTree パラメータはすべてのファインダーで使用できます。たとえば、ここに onNodeWithText ファインダーで使用されます。

composeTestRule
    .onNodeWithText("World", useUnmergedTree = true).assertIsDisplayed()

アサーション

SemanticsNodeInteractionassert() を呼び出して、アサーションを確認します。 1 つまたは複数のマッチャーを使用して検索すると返されることはありません。

// 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"))

また、次のような最も一般的なアサーションに便利な関数を使用することもできます。 assertExistsassertIsDisplayedassertTextEquals。 完全なリストは、Compose テストのクイック リファレンスをご覧ください。

ノードのコレクションでアサーションを確認する関数もあります。

// 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())

アクション

ノードにアクションを挿入するには、perform…() 関数を呼び出します。

composeTestRule.onNode(...).performClick()

アクションの例を次に示します。

performClick(),
performSemanticsAction(key),
performKeyPress(keyEvent),
performGesture { swipeLeft() }

完全なリストについては、Compose テスト クイック リファレンスをご覧ください。

マッチャー

Compose のテストにさまざまなマッチャーを利用できる 説明します。

階層マッチャー

階層型マッチャーを使用すると、セマンティクス ツリーを上下に移動して、 あります。

fun hasParent(matcher: SemanticsMatcher): SemanticsMatcher
fun hasAnySibling(matcher: SemanticsMatcher): SemanticsMatcher
fun hasAnyAncestor(matcher: SemanticsMatcher): SemanticsMatcher
fun hasAnyDescendant(matcher: SemanticsMatcher):  SemanticsMatcher

こうしたマッチャーの例を次に示します。

composeTestRule.onNode(hasParent(hasText("Button")))
    .assertIsDisplayed()

セレクタ

テストを作成する別の方法として、セレクタを使用する方法があります。これにより、一部のテストが読みやすくなります。

composeTestRule.onNode(hasTestTag("Players"))
    .onChildren()
    .filter(hasClickAction())
    .assertCountEquals(4)
    .onFirst()
    .assert(hasText("John"))

完全なリストは、Compose テストのクイック リファレンスをご覧ください。

参考情報