テスト API

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

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

これらの API の一部は、セマンティクス ツリー内の 1 つ以上のノードを参照するために SemanticsMatcher を受け入れます。

ファインダー

onNodeonAllNodes を使用して 1 つまたは複数のノードを個別に選択できますが、onNodeWithTextonNodeWithContentDescription などの一般的な検索でコンビニエンス ファインダーを使用することもできます。完全なリストについては、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()

アサーション

1 つ以上のマッチャーを使用してファインダーから返された SemanticsNodeInteraction に対して assert() を呼び出して、アサーションをチェックします。

// 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 テストのクイック リファレンスで確認できます。

その他のリソース

  • Android でアプリをテストする: Android テストのメイン ランディング ページでは、テストの基礎と手法について幅広く確認できます。
  • テストの基礎: Android アプリのテストの基本コンセプトについて説明します。
  • ローカルテスト: 一部のテストは、自分のワークステーションでローカルに実行できます。
  • インストルメンテーション テスト: インストルメンテーション テストも実行することをおすすめします。つまり、デバイス上で直接実行されるテストです。
  • 継続的インテグレーション: 継続的インテグレーションを使用すると、テストをデプロイ パイプラインに統合できます。
  • さまざまな画面サイズをテストする: ユーザーが利用できるデバイスが多数ある場合は、さまざまな画面サイズでテストする必要があります。
  • Espresso: Espresso の知識はビューベースの UI を対象としていますが、Compose テストの一部では Espresso の知識が役立ちます。