Robo スクリプト リファレンス ガイド

このドキュメントでは、Robo スクリプトに関するリファレンス情報(構造、機能、使用方法、記録、アクションなど)を提供します。Robo スクリプトは、モバイルアプリの手動品質保証(QA)タスクを自動化し、継続的インテグレーション(CI)とリリース前テスト戦略を可能にするテストです。Robo スクリプトは、一連のユーザー インターフェース(UI)やその他のアクションを記述する JSON ファイルです。

Robo スクリプトは次の方法で作成できます。

  • Robo スクリプトの記録機能を使用します。 (Android デバイスのみ)。

  • Robo スクリプトを手動で作成します。 (Android、iOS+)

  • Robo スクリプトを記録してから、手動で編集します。 (Android デバイスのみ)。

Robo スクリプトの使用の詳細については、Robo スクリプトを実行するをご覧ください。

はじめに

Robo スクリプトは、テスト対象アプリの App Application Package(APK)などの他の入力とともに Robo テストに提供されます。

ユーザーをアプリにログインさせる Robo スクリプトの例を次に示します。これは、テスト対象アプリが起動したときにトリガーされます。

[
  {
    "crawlStage": "crawl",
    "contextDescriptor": {
      "condition": "app_under_test_shown"
    },
    "actions": [
      {
        "eventType": "VIEW_TEXT_CHANGED",
        "replacementText": "user123",
        "elementDescriptors": [
          {
            "resourceId": "my.app.package:id/username"
          }
        ]
      },
      {
        "eventType": "VIEW_TEXT_CHANGED",
        "replacementText": "12345",
        "elementDescriptors": [
          {
            "resourceId": "my.app.package:id/password"
          }
        ]
      },
      {
        "eventType": "VIEW_CLICKED",
        "elementDescriptors": [
          {
            "resourceId": "my.app.package:id/login"
          }
        ]
      }
    ]
  }
]

上記の例のように、ファイル内に Robo スクリプトが 1 つあり、デフォルトの app_under_test_shown トリガー条件がある場合は、アクションの順序を示すだけの単純な形式でファイルに Robo スクリプトを指定できます。

[
  {
    "eventType": "VIEW_TEXT_CHANGED",
    "replacementText": "user123",
    "elementDescriptors": [
      {
        "resourceId": "my.app.package:id/username"
      }
    ]
  },
  {
    "eventType": "VIEW_TEXT_CHANGED",
    "replacementText": "12345",
    "elementDescriptors": [
      {
        "resourceId": "my.app.package:id/password"
      }
    ]
  },
  {
    "eventType": "VIEW_CLICKED",
    "elementDescriptors": [
      {
        "resourceId": "my.app.package:id/login"
      }
    ]
  }
]

Robo スクリプトの iOS+ サポート

iOS+ 用 Robo(ベータ版)は、Robo スクリプトを制限付きでサポートしています。iOS+ の Robo スクリプトの構文は Android の構文と同一であり、サポートされている iOS+ 機能は Android の同等の機能と同様に動作します。

iOS 以降では、次のアクションがサポートされています。

  • アサーション
  • クリック
  • 長押し
  • スワイプ
  • すべての要素を無視する
  • 待機
  • スクリーンショットを撮る
  • クロールを終了する

iOS+ では、要素記述子に含まれる次の識別属性がサポートされています。

  • クラス名
  • 祖先のクラス名
  • コンテンツの説明(および正規表現)
  • テキスト(および正規表現)

iOS+ では、コンテキスト記述子で次のトリガー条件がサポートされています。

  • テスト対象のアプリが表示された
  • 要素がある
  • Robo スクリプト以外のアクションが実行された

構造

Robo スクリプトには、Robo による実行方法を示すいくつかの属性があります。これらの属性のほとんどは省略可能であり、デフォルト値が事前定義されています。

属性 説明
id クロール出力でこの Robo スクリプトを追跡するのに役立つ整数。 Robo には、独自の id を持つ Robo スクリプトが組み込まれています。異なる Robo スクリプト内の同じ id は動作に影響しませんが、クロール出力でこれらの Robo スクリプトのアクションを区別するのは難しい場合があります。競合を回避するため、Robo スクリプトに一意の id1000 以上)を割り当てることをおすすめします。
description id に似ていますが、より記述的なものです。
crawlStage この Robo スクリプトが適用されるクロールのステージ。デフォルトはメインのクロール ステージです。
priority 他の Robo スクリプトとの比較での、この Robo スクリプトの優先度。デフォルトでは、すべての Robo スクリプトの優先度は 1 です。
maxNumberOfRuns クロール中にこの Robo スクリプトを実行できる回数を指定します。デフォルトでは、Robo スクリプトは 1 回だけ実行できます。
contextDescriptor この Robo スクリプトをトリガーするコンテキストまたは条件を記述します。省略した場合、この Robo スクリプトのトリガー条件は常に満たされているものとみなされます。つまり、Robo スクリプトは無条件となります。
actions この Robo スクリプトのすべてのアクション。

1 つのファイルには、1 つまたは複数の Robo スクリプトのコレクションが含まれます。

以下に、2 つの無条件 Robo スクリプトを含むファイルの例を示します。各スクリプトには、クロールの開始時に 1 回実行される 1 つのアクションが含まれています。

[
  {
    "id": 1000,
    "description": "My first Robo script",
    "actions": [
      {
        "eventType": "DISABLE_KEYBOARD"
      }
    ]
  },
  {
    "id": 1001,
    "description": "My second Robo script",
    "actions": [
      {
        "eventType": "PRESSED_BACK"
      }
    ]
  }
]

コンテキスト記述子

コンテキスト記述子は、1 つの属性または複数の属性の組み合わせを使用して、Robo スクリプトをトリガーするためのコンテキストまたは条件を定義します。

属性 説明
"condition": "always" 常に Robo スクリプトがトリガーされます。
"condition": "element_present" elementDescriptors に一致する、または visionText で指定されたテキストに一致する UI ウィジェットが画面に存在することを確認します。
"condition": "element_disabled" elementDescriptors に一致する UI ウィジェットが画面上に存在し、操作できないことを確認します。
"condition": "element_checked" elementDescriptors に一致する UI ウィジェットが画面上に存在し、チェックボックスがオンになっていることを確認します。
"condition": "app_under_test_shown" テスト対象のアプリがフォアグラウンドで実行されていることを確認します。
"condition": "default_launcher_shown" デバイスのホーム画面が表示されていることを確認します。フォアグラウンドで実行されているアプリはありません。
"condition": "non_roboscript_action_performed" Robo テストによって実行された最後の nonRoboscriptActionCount 連続アクションが Robo スクリプト アクションでないことを確認します。
negateCondition true に設定すると、condition が無効になります。たとえば、この属性を使用して、UI ウィジェットが画面に存在しないか確認したり、テスト対象のアプリがフォアグラウンドで実行されていないことを確認したりできます。
elementDescriptors 画面上の UI ウィジェットを識別する 1 つ以上の要素記述子。element_present 条件、element_disabled 条件および element_checked 条件と組み合わせて使用します。visionText とは相互に排他的です。詳細については、要素記述子をご覧ください。
visionText 画面上のテキストは、光学式文字認識(OCR)API を使用して検出されます。visionText は、element_present 条件と組み合わせて使用されます。elementDescriptors とは相互に排他的です。
nonRoboscriptActionCount 以前に実行された Robo スクリプト以外の連続アクションの数。non_roboscript_action_performed 条件と組み合わせて使用し、すべての nonRoboscriptActionCount Robo のアクションの後に Robo スクリプトをトリガーします。デフォルトでは 1 になっています。

次の例は、リソース ID が "my.app.package:id/page_header" の UI ウィジェットが画面上に存在する場合にトリガーされる Robo スクリプトです。

{
  "id": 1000,
  "contextDescriptor": {
    "condition": "element_present",
    "elementDescriptors": [
      {
        "resourceId": "my.app.package:id/page_header"
      }
    ]
  },
  "actions": [
    {
      "eventType": "VIEW_CLICKED",
      "elementDescriptors": [
        {
          "text": "Settings"
        }
      ]
    }
  ]
}

次の例は、光学式文字認識(OCR)によって "Privacy Policy" が検出された場合にトリガーされる Robo スクリプトです。

{
  "id": 1000,
  "description": "Vision text Robo script",
  "contextDescriptor": {
    "condition": "element_present",
    "visionText": "Privacy Policy"
  },
  "actions": [
    {
      "eventType": "VIEW_CLICKED",
      "visionText": "Privacy Policy"
    }
  ]
}

次の例は、スクリプト以外の Robo アクションが行われた後に 5 秒間待機する Robo スクリプトです。

{
  "contextDescriptor": {
    "condition": "non_roboscript_action_performed"
  },
  "maxNumberOfRuns" : 1000,
  "actions" : [
    {
      "eventType" : "DELAYED_MESSAGE_POSTED",
      "delayTime" : 5000
    }]
}

アクション

Robo スクリプトの各アクションは、次の表に記載しているように、属性と値のペア(1 つ以上)からなるバンドルとして表されます。

属性 説明
eventType アクションのタイプ(クリック、テキスト編集など)を指定します。すべてのアクションで必要です。
elementDescriptors UI ウィジェットを識別する記述子。特定ボタンのクリックなど、ターゲット UI ウィジェットを持つすべてのアクションで必要です。
optional true に設定すると、このアクションを実行できない場合にスキップされます。たとえば画面上でターゲット UI ウィジェットが見つからない場合、このアクションはスキップされます。アクションが含まれている Robo スクリプトは失敗しません。デフォルトでは、値は false です。
replacementText ターゲット UI ウィジェットに入力するテキスト。テキスト編集アクションに必要です。
swipeDirection スワイプの方向を指定します。スワイプ操作に必要です。
delayTime 待機時間をミリ秒単位で指定します。待機アクションに必要です。
pointTapXCoordinate および pointTapYCoordinate タップされるポイントのピクセル X 座標と Y 座標。pointTapXPercentpointTapYPercent とは相互に排他的です。ポイント タップ アクションに必要です。
pointTapXPercent および pointTapYPercent タップされるポイントのパーセンテージ X 座標と Y 座標。pointTapXCoordinatepointTapYCoordinate とは相互に排他的です。ポイント タップ アクションに必要です。

以下に、ターゲット UI ウィジェットのない(アクションの対象となる特定の UI ウィジェットのない)2 つのアクションを含む Robo スクリプトの例を示します。

[
  {
    "eventType": "DELAYED_MESSAGE_POSTED",
    "delayTime": 3000
  },
  {
    "eventType": "PRESSED_BACK"
  }
]

要素記述子

要素記述子は、次のうち 1 つ以上の識別属性を使用して UI ウィジェットを識別します。

属性 説明
className
ancestorClassName 要素の UI 階層の祖先のクラス名。祖先とは、要素の UI 階層に含まれる親ノードのいずれかで、その要素自体も含みます。
resourceId
resourceIdRegex resourceId と一致する Java 正規表現。
contentDescription
contentDescriptionRegex contentDescription と一致する Java 正規表現。
text(画面に表示されます)
textRegex text と一致する Java 正規表現。
groupViewChildPositionrecyclerViewChildPosition、または adapterViewChildPosition UI ウィジェットの子の位置(親ウィジェットの種類によって異なります)。

多くの場合、これらの属性は未定義です。たとえば、ボタンにテキストやコンテンツの説明がない場合があります。一部の属性値が存在する場合でも、特定のアプリ画面(resourceId など)で一意でない場合があります。

このため、リスト内のアイテムを区別する基準は、親ウィジェット内のそれぞれの子の位置のみであるという状態が多く発生します。これは、UI ウィジェットの識別に 1 つの要素記述子を使用するだけでは、通常は不十分であることを意味します。したがって、アクションの elementDescriptors 属性には一連の要素記述子が含まれ、最初の記述子がターゲット UI ウィジェットに、2 番目の記述子がターゲット UI ウィジェットの親ウィジェットに対応するように順序付けられます。すべての要素記述子が、対応する UI ウィジェットのサブ階層と一致する場合に、アクションのターゲット UI ウィジェットは一致したものとみなされます。

テキストの変更とクリック操作を含む Robo スクリプトの例を次に示します。どちらも、提供された要素記述子を使用して、ターゲット UI ウィジェットを識別する必要があります。

[
  {
    "eventType": "VIEW_TEXT_CHANGED",
    "replacementText": "John",
    "elementDescriptors": [
      {
        "className": "android.support.v7.widget.AppCompatEditText",
        "groupViewChildPosition": 0,
        "resourceId": "com.google.samples.apps.topeka:id/first_name"
      },
      {
        "className": "android.widget.FrameLayout",
        "groupViewChildPosition": 0
      },
      {
        "className": "android.support.design.widget.TextInputLayout",
        "groupViewChildPosition": 1
      }
    ]
  },
  {
    "eventType": "VIEW_CLICKED",
    "elementDescriptors": [
      {
        "className": "android.support.design.widget.FloatingActionButton",
        "groupViewChildPosition": 1,
        "resourceId": "com.google.samples.apps.topeka:id/done"
      },
      {
        "className": "android.widget.FrameLayout",
        "groupViewChildPosition": 1,
        "resourceId": "com.google.samples.apps.topeka:id/content"
      },
      {
        "className": "android.widget.FrameLayout",
        "groupViewChildPosition": 0,
        "resourceId": "com.google.samples.apps.topeka:id/sign_in_content"
      }
    ]
  }
]

実行オプション

必要に応じて、Robo スクリプトのアクション リストの先頭に、その Robo スクリプトの実行オプションを指定する JSON オブジェクトを付加することができます。この構成ヘッダーは roboscript キーワードで始まり、その後に目的の実行オプションの JSON 表現が続きます。

Robo スクリプトでは、次の実行オプションがサポートされています。

  • executionMode - Robo スクリプトの実行中に適用される実行オプション。
    • strict - true に設定すると、Robo スクリプトは部分一致、現在のアクションのスキップ、停止を使用しません。つまり、Robo スクリプトは通常のインストルメンテーション テストとして実行され、いずれかのアクションを実行できなくなるとその時点で失敗します。 デフォルトでは false になっています。
    • dismiss_popups - true に設定すると、strict モードでも、Robo スクリプトの実行中に予期しないダイアログが閉じられます。このオプションは、strict モード以外では効果がありません。デフォルトでは false になっています。
    • notify - false に設定すると、Robo スクリプトは実行の開始時と終了時に画面上の通知を表示しません。デフォルトでは true になっています。
  • postscript - Robo スクリプトの完了後に適用される実行オプション。
    • terminate - true に設定すると、Robo スクリプトが完了した時点で Robo テストはクロールを停止します。 デフォルトでは false になっています。

下記は、画面上の通知は表示されずに strict モードで実行され、3 秒間スリープしたのちにクロールが停止される Robo スクリプトの例です。

"roboscript": {
  "executionMode": {
    "strict": true,
    "notify": false
  },
  "postscript": {
    "terminate": true
  }
}
[
  {
    "eventType": "DELAYED_MESSAGE_POSTED",
    "delayTime": 3000
  }
]

テンプレートのパラメータ

テンプレートのパラメータは Robo スクリプト内のプレースホルダであり、Robo テストが実行のためにその Robo スクリプトを読み込むときに、実際の値に置き換えられます。テンプレートのパラメータには、接頭辞としてアンダースコアが 2 つ、その後にパーセント記号が 1 つ付きます。また、接尾辞としてパーセント記号が 1 つ、その後にアンダースコアが 2 つ付きます。

Robo スクリプトでは、次のテンプレートのパラメータがサポートされています。

  • __%APP_PACKAGE_NAME%__ - テスト対象のアプリのパッケージ名。

以下は、テスト対象のアプリのプロセスを停止する Robo スクリプトの例です。

[
  {
    "eventType": "ADB_SHELL_COMMAND",
    "command": "am force-stop __%APP_PACKAGE_NAME%__"
  }
]

コメント

Robo スクリプトには、# または // で始まるコメント行を含めることができます。

以下に、いくつかのコメントがある Robo スクリプトの例を示します。

# Confirm a user account.
[
  {
    // Click the DONE button.
    "eventType": "VIEW_CLICKED",
    "elementDescriptors": [
      {
        "resourceId": "com.google.samples.apps.topeka:id/done"
      }
    ]
  }
]

機能

デフォルトでは、Robo スクリプトのすべてのアクションが完了(または少なくとも試行)されるまで、Robo スクリプトはアクティブなままになります。Robo テストは、実行するアクションを選択するたびに Robo スクリプトのアクションを一致させようとします。Robo スクリプトでは、次の手法を使用して堅牢性を高めています。

手法 説明
部分一致 現在の Robo スクリプトのアクションが完全一致しない場合、一致条件が緩和され、一致が再試行されます。部分一致では、Robo スクリプト アクションとターゲット UI ウィジェットとの一致の際、一番外側の要素記述子は考慮されません。

部分一致が成功すると、対応する Robo スクリプトのアクションが通常どおり実行されます。この手法は、アプリ バージョン間で画面要素が再配置された場合など、アプリ構造が変化するシナリオをサポートします。

現在のアクションをスキップ 現在の Robo スクリプトのアクションを全部または部分的に一致させることができない場合、Robo は後続の Robo スクリプトのアクションとの一致を試みます。後続のアクションが全部または部分的に一致する場合、Robo テストは現在の Robo スクリプトのアクションをスキップし(戻ることはありません)、後続のアクションを実行します。

この手法は、バージョン間でアプリの動作が変化する、または不安定な場合(Robo スクリプトの記録時と再生時に、異なる画面に断続的なダイアログが表示される場合など)に対応します。

停止 現在および後続の Robo スクリプトのアクションのいずれも、全部または部分的に一致させることができない場合、Robo スクリプトは一時的に停止され、Robo テストは他の戦略を使用して実行するアクションを選択します。このアクションが完了すると、Robo テストは Robo スクリプトの実行を再開します。

現在または後続の Robo スクリプトのアクションが一致しない限り、Robo スクリプトは複数のアクションで停止されたままとなります。そのため、Robo スクリプトは Robo テストに先立つ必要はなく、Robo スクリプト アクションを標準の Robo テスト アクションと混在させることができます。この手法は、アプリの動作が不安定な場合、またはアプリのバージョン間の変更が大きいために Robo テストが標準のアクションで補完する必要がある場合のシナリオをサポートします。

優先事項

Robo スクリプトが maxNumberOfRuns に達すると、クロールの中でトリガーできなくなります。現在のコンテキストで複数の Robo スクリプトをトリガーできる場合は、以下の条件に基づいて(以下の記述順で判断)Robo スクリプトの優先度が決定されます。

  1. contextDescriptor 属性が記述されている。
  2. 最も高い priority を持つ(デフォルトでは、すべての Robo スクリプトの priority は同じく 1 です)。
  3. Robo スクリプトの優先度が同じである場合、Robo スクリプトのリストの上のほうにある。

以下は、同じアクションを実行し、同じ条件(テスト対象アプリがフォアグラウンドにある)でトリガーされる 3 つの Robo スクリプトを含むファイルの例です。

[
  {
    "id": 1000,
    "description": "Robo script 1",
    "contextDescriptor": {
      "condition": "app_under_test_shown"
    },
    "actions": [
      {
        "eventType": "DELAYED_MESSAGE_POSTED",
        "delayTime": 3000
      }
    ]
  },
  {
    "id": 1001,
    "description": "Robo script 2",
    "priority": "2",
    "contextDescriptor": {
      "condition": "app_under_test_shown"
    },
    "actions": [
      {
        "eventType": "DELAYED_MESSAGE_POSTED",
        "delayTime": 3000
      }
    ]
  },
  {
    "id": 1002,
    "description": "Robo script 3",
    "contextDescriptor": {
      "condition": "app_under_test_shown"
    },
    "actions": [
      {
        "eventType": "DELAYED_MESSAGE_POSTED",
        "delayTime": 3000
      }
    ]
  }
]

テスト対象アプリがフォアグラウンドにある場合、Robo スクリプトが次の順番でトリガーされます。

  1. "Robo script 2"。優先度が最も高いためです。
  2. "Robo script 1"。残りの適用可能な Robo スクリプト(同じ優先度)の中で上のほうにあるためです。
  3. "Robo script 3"。適用可能な最後の Robo スクリプトです。

繰り返し実行

デフォルトでは、1 つの Robo スクリプトはクロール中に 1 回だけトリガーされます。この回数は maxNumberOfRuns 属性で調整できます。

以下は、テスト対象アプリを最大 10 回バックグラウンドに移動する Robo スクリプトの例です。

{
  "id": 1000,
  "maxNumberOfRuns": 10,
  "contextDescriptor": {
    "condition": "app_under_test_shown"
  },
  "actions": [
    {
      "eventType": "GO_HOME"
    }
  ]
}

クロール ステージ

Robo スクリプトは、Robo クロールのさまざまなステージに適用できます。

クロール ステージ 説明
pre_crawl Robo が起動してテスト対象アプリのクロールを開始する前。
post_crawl Robo がテスト対象アプリのクロールを完了した後。 post_crawl Robo スクリプトの長さは 15 秒を超えないようにしてください。長すぎると、クロールがタイムアウトで終了する可能性があります。
crawl Robo がテスト対象アプリをクロールする際のメインのクロール ステージ。
close_screen Robo がある画面から戻ろうとするときに(バックトラック)、その画面で可能なすべてのアクションが探索されます。デフォルトでは、Robo は戻るボタンを押しますが、これは望ましくない場合があります。

Robo スクリプトに crawlStage 属性が指定されていない場合は、暗黙的に crawl と想定されます。

以下に、クロールを開始する前に、テスト対象アプリのユーザーデータを消去する Robo スクリプトの例を示します。

{
  "id": 1000,
  "crawlStage": "pre_crawl",
  "actions": [
    {
      "eventType": "ADB_SHELL_COMMAND",
      "command": "pm clear __%APP_PACKAGE_NAME%__"
    }
  ]
}

以下に、確認ダイアログから戻ろうとする(バックトラック)たびに "Cancel" をクリックするよう Robo に指示する Robo スクリプトの例を示します。

{
  "id": 1000,
  "crawlStage": "close_screen",
  "maxNumberOfRuns": 999,
  "contextDescriptor": {
    "condition": "element_present",
    "elementDescriptors": [
      {
        "resourceId": "my.app.package:id/confirmation_dialog"
      }
    ]
  },
  "actions": [
    {
      "eventType": "VIEW_CLICKED",
      "elementDescriptors": [
        {
          "text": "Cancel"
        }
      ]
    }
  ]
}

条件付きアクション

Robo スクリプトには条件付きアクションを含めることができます。条件付きアクションには、Robo による実行方法を記述する 3 つの属性があります。

属性 説明
priority 含まれている Robo スクリプト内の他の条件付きアクションと比較した場合の、この条件付きアクションの優先度。デフォルトでは、すべての条件付きアクションの優先度は 1 です。
maxNumberOfRuns 条件付きアクションが含まれている Robo スクリプトの 1 回の実行中に、この条件付きアクションを実行できる回数。デフォルトでは、条件付きアクションが含まれている Robo スクリプトの 1 回の実行において、すべての条件付きアクションは 1 回だけ実行できます。
contextDescriptor この条件付きアクションをトリガーするコンテキストまたは条件。これは Robo スクリプトの contextDescriptor と同じ構造を持ち、同様の機能を提供します。

トリガーされると、Robo スクリプトは無条件アクションを、記述されている順に 1 つずつ実行します。Robo スクリプトに条件付きアクションが含まれている場合は、実行する無条件アクションを選択する前に、条件付きアクションが考慮されます。優先度と残りの実行回数に基づいて条件付きアクションがトリガーされ、選択されると、Robo スクリプトはこの条件付きアクションを実行します。条件付きアクションが選択されなかった場合は、Robo スクリプトは後続の無条件アクションを実行します。Robo スクリプトが有効であるためには、Robo スクリプト内に少なくとも 1 つの無条件アクションが含まれている必要があります。

以下は、Robo スクリプトの実行中にポップアップ ダイアログが表示されたときにそれを閉じる条件付きアクションを含む、無条件 Robo スクリプトの例です。

{
  "id": 1000,
  "actions": [
    {
      "description": "Dismiss popup",
      "maxNumberOfRuns": 100,
      "contextDescriptor": {
        "condition": "default_launcher_shown",
        "negateCondition": true
      },
      "eventType": "GO_HOME"
    },
    {
      "description": "Screen off",
      "eventType": "ADB_SHELL_COMMAND",
      "command": "input keyevent 26"
    },
    {
      "description": "Wait for 10 seconds",
      "eventType": "DELAYED_MESSAGE_POSTED",
      "delayTime": 10000
    },
    {
      "description": "Screen on",
      "eventType": "ADB_SHELL_COMMAND",
      "command": "input keyevent 82"
    },
    {
      "description": "Wait for 10 seconds",
      "eventType": "DELAYED_MESSAGE_POSTED",
      "delayTime": 10000
    }
}

無視アクション

Robo スクリプトには、特定の画面上の特定の UI ウィジェットまたはすべての UI ウィジェットを無視するように指示する命令を含めることができます。これらの命令は、eventType がそれぞれ ELEMENT_IGNOREDALL_ELEMENTS_IGNORED の無視アクションとして記述します。

無視アクションを含む Robo スクリプトの contextDescriptor 属性が特定の画面と一致すると、Robo は、その無視アクションの対象として指定されている UI ウィジェットを操作しません(ただし、無視の対象となっている UI ウィジェットに対して、他の Robo スクリプト アクションの実行が指定されている場合は、そのアクションが実行されます)。

Robo スクリプトには、無視アクション、条件付きアクション、無条件アクションを組み合わせて含めることができます。Robo スクリプトの他のアクションとは異なり、Robo のクロール中に、無視アクションが含まれている Robo スクリプトの contextDescriptor が画面に一致すると、prioritymaxNumberOfRuns 属性の値は考慮されずにその無視アクションが適用されます。

2 つの Robo スクリプトを含むファイルの例を次に示します。最初の Robo スクリプトでは、リソース ID が "my.app.package:id/ignored_screen" の UI ウィジェットが含まれる画面において、すべての UI ウィジェットを無視するように指定します。2 つ目の Robo スクリプトでは、リソース ID が "my.app.package:id/main_screen" の UI ウィジェットが含まれる画面において、リソース ID が Java 正規表現 ".*:id/done" と一致する UI ウィジェットを無視するように指定します。

[
  {
    "id": 1000,
    "contextDescriptor": {
      "condition": "element_present",
      "elementDescriptors": [
        {
          "resourceId": "my.app.package:id/ignored_screen"
        }
      ]
    },
    "actions": [
      {
        "eventType": "ALL_ELEMENTS_IGNORED"
      }
    ]
  },
  {
    "id": 1001,
    "contextDescriptor": {
      "condition": "element_present",
      "elementDescriptors": [
        {
          "resourceId": "my.app.package:id/main_screen"
        }
      ]
    },
    "actions": [
      {
        "eventType": "ELEMENT_IGNORED",
        "elementDescriptors": [
          {
            "resourceIdRegex": ".*:id/done"
          }
        ]
      }
    ]
  }
]

RecyclerView と AdapterView のサポート

RecyclerView ウィジェットと AdapterView ウィジェットの子は動的に読み込まれるため、現在の画面から何回もスワイプしないと表示されない場合があります。画面のサイズ、およびこの子に到達するために必要なスワイプの数は、デバイスのフォーム ファクタによって異なるため、絶対的な子のデータ位置に依存する方がはるかに堅牢です。この子を画面に移動してその画面の位置を使用するために必要なスワイプの数に依存すると、堅牢性が低下します。

そのため Robo スクリプトは、Robo スクリプト アクションの対象となる RecyclerView の子の絶対データ位置を recyclerViewChildPosition としてキャプチャします。Robo スクリプトは、Robo スクリプト アクションの対象となる AdapterView の子の絶対データ位置を adapterViewChildPosition としてキャプチャします。

RecyclerView と AdapterView の子に対するアクションは、次の手順で行われます。

  1. Robo テストでは、対応する子が、含まれている RecyclerView または AdapterView 上の位置指定アクションを通じて画面に表示されることを確認します。

  2. Robo テストでは、すでに画面に表示されているため、記録されたアクションを子要素に対して直接実行します。

以下に、AdapterView(android.widget.GridView)の子に対するクリック アクションの例を示します。

{
  "eventType": "VIEW_CLICKED",
  "elementDescriptors": [
    {
      "className": "com.google.samples.apps.topeka.widget.AvatarView",
      "adapterViewChildPosition": 5,
      "resourceId": "com.google.samples.apps.topeka:id/avatar",
      "contentDescription": "Avatar 6"
    },
    {
      "className": "android.widget.GridView",
      "groupViewChildPosition": 1,
      "resourceId": "com.google.samples.apps.topeka:id/avatars"
    },
    {
      "className": "android.widget.LinearLayout",
      "groupViewChildPosition": 1
    },
    {
      "className": "android.widget.LinearLayout",
      "groupViewChildPosition": 0
    }
  ]
}

以下は、RecyclerView(android.support.v7.widget.RecyclerView)の子に対するクリック アクションの例です。

{
  "eventType": "VIEW_CLICKED",
  "elementDescriptors": [
    {
      "className": "android.support.v7.widget.AppCompatTextView",
      "groupViewChildPosition": 1,
      "resourceId": "com.google.samples.apps.topeka:id/category_title"
    },
    {
      "className": "android.widget.FrameLayout",
      "recyclerViewChildPosition": 8,
      "resourceId": "com.google.samples.apps.topeka:id/category_item"
    },
    {
      "className": "android.support.v7.widget.RecyclerView",
      "groupViewChildPosition": 1,
      "resourceId": "com.google.samples.apps.topeka:id/categories"
    },
    {
      "className": "android.widget.FrameLayout",
      "groupViewChildPosition": 1,
      "resourceId": "com.google.samples.apps.topeka:id/category_container"
    },
    {
      "className": "android.widget.LinearLayout",
      "groupViewChildPosition": 0
    }
  ]
}

Android Studio で Robo スクリプトを記録し、Test Lab で実行する

Android Studio で Robo スクリプトを作成できます。スクリプトは JSON ファイルとして保存されます。その後、アプリケーションを使用して JSON ファイルを Firebase Test Lab にアップロードし、テストを実行できます。

スクリプトを添付した状態で Robo テストを実行すると、Robo テストはまずスクリプトに記述されたアクションを実行してから、通常どおりアプリを調べます。

Android Studio で Robo スクリプト JSON ファイルを作成するには、Android Studio で Test Lab を使用して Robo スクリプトを記録するの手順を行ってください。

Robo スクリプト アクション

次の一般的なオプション属性は、すべてのアクションに適用されます。

  • description - Robo テスト出力で Robo スクリプト アクションの実行を追跡するのに役立ちます。

アサーション

アサートの条件が true であった場合、Robo スクリプトは次のアクションに進みます。次のアクションがまた別のアサーションである場合もあります。アサートの条件が false であった場合は、アサーションに失敗して Robo スクリプトの実行が停止します。

次の表に、必要な属性を示します。

属性 説明
"eventType": "ASSERTION" --
contextDescriptor アサートするコンテキストまたは条件を記述します。これは Robo スクリプトの contextDescriptor と同じ構造を持ち、同様の機能を提供します。

以下は、テスト対象のアプリがフォアグラウンドにあることを確認する Robo スクリプト アサーションの例です。

{
  "eventType": "ASSERTION",
  "contextDescriptor": {
    "condition": "app_under_test_shown"
  }
}

次は、リソース ID が "com.google.samples.apps.topeka:id/done" の UI ウィジェットが画面上に存在することを確認する Robo スクリプト アサーションの例です。

{
  "eventType": "ASSERTION",
  "contextDescriptor": {
    "condition": "element_present",
    "elementDescriptors": [
      {
        "resourceId": "com.google.samples.apps.topeka:id/done"
      }
    ]
  }
}

次は、OCR を使用して画面上で "Settings" が検出されないことを確認する Robo スクリプト アサーションの例です。

{
  "eventType": "ASSERTION",
  "contextDescriptor": {
    "condition": "element_present",
    "negateCondition": true,
    "visionText": "Settings"
  }
}

クリック

次の表に、必要な属性を示します。

属性説明
eventType Robo スクリプト アクションのタイプを指定します。
"eventType": "VIEW_CLICKED" テスト対象アプリのターゲット要素をクリックします。
"eventType": "SOFT_KEYBOARD_CLICK" ソフト キーボードのターゲット要素をクリックします。
"eventType": "SOFT_KEYBOARD_RANDOM_CLICK" ソフト キーボードのランダムな要素を maxNumberOfRuns 回までクリックします。
"eventType": "LIST_ITEM_CLICKED" リストアイテムをクリックするために Android Studio の Robo スクリプト レコーダーが使用します。
elementDescriptors Android UI 階層を使用して、クリックされた UI ウィジェットを識別します。visionText とは相互に排他的です。
visionText OCR を使用して、クリックされた要素を識別します。elementDescriptors とは相互に排他的です。
maxNumberOfRuns eventTypeSOFT_KEYBOARD_RANDOM_CLICK の場合に、ソフト キーボードのランダムな要素をクリックする回数を指定します。デフォルト値は 1 です。

リソース ID "com.google.samples.apps.topeka:id/done" のボタンをクリックする Robo スクリプト アクションの例を次に示します。

{
  "eventType": "VIEW_CLICKED",
  "elementDescriptors": [
    {
      "resourceId": "com.google.samples.apps.topeka:id/done"
    }
  ]
}

OCR を使用して画面上で検出された "Privacy Policy" をクリックする Robo スクリプト アクションの例を次に示します。

{
  "eventType": "VIEW_CLICKED",
  "visionText": "Privacy Policy"
}

次に、コンテンツの説明が "Emoji button" のソフト キーボード要素をクリックする Robo スクリプト アクションの例を示します。

{
  "eventType": "SOFT_KEYBOARD_CLICK",
  "elementDescriptors": [
    {
      "contentDescription": "Emoji button"
    }
  ]
}

ソフト キーボード要素をランダムに最大 5 回クリックする Robo スクリプト アクションの例を次に示します。

{
  "eventType": "SOFT_KEYBOARD_RANDOM_CLICK",
  "maxNumberOfRuns": 5
}

ソフト キーボードを無効にする

次の表に、必要な属性を示します。

属性 説明
"eventType": "DISABLE_KEYBOARD" --

ソフト キーボードを無効にする Robo スクリプト アクションの例を次に示します。

{
  "eventType": "DISABLE_KEYBOARD"
}

adb シェルのコマンドを実行する

次の表に、必要な属性を示します。

属性 説明
"eventType": "ADB_SHELL_COMMAND" --
command 実行する Android Debug Bridge(adb)シェルのコマンド。

次の属性は省略可能です。

  • expectedOutputRegex - コマンドで想定される Java 正規表現形式の出力。出力が一致しない場合、Robo スクリプトのアクションは失敗します。デフォルトでは空の文字列であるため、出力はチェックされません。

次に、テスト対象アプリのユーザーデータを消去する Robo スクリプト アクションの例を示します。

{
  "eventType": "ADB_SHELL_COMMAND",
  "command": "pm clear __%APP_PACKAGE_NAME%__"
}

権限を付与する

このアクションは、Espresso テスト レコーダーとの下位互換性を維持するため、Android Studio の Robo スクリプト レコーダーによって記録されます。Robo テストでは、すべてのクロールの開始時にテスト対象アプリにすべての権限が付与されるため、このアクションは行われません。このアクションは、Robo スクリプトでは使用しないでください。

次の表に、必要な属性を示します。

属性 説明
"eventType": "PERMISSIONS_REQUEST" --

画面上のすべての要素を無視する

このアクションは、それが含まれている Robo スクリプトをトリガーするすべての画面において、すべての要素を無視するように指示します。

次の表に、必要な属性を示します。

属性 説明
"eventType": "ALL_ELEMENTS_IGNORED" --

画面上のすべての要素を無視する Robo スクリプト アクションの例を次に示します。

{
  "eventType": "ALL_ELEMENTS_IGNORED"
}

要素を無視する

このアクションは、指定された elementDescriptors に一致する 1 つまたは複数の要素を無視するように指示します。

次の表に、必要な属性を示します。

属性 説明
"eventType": "ELEMENT_IGNORED" --
elementDescriptors Android UI 階層を使用して、無視する UI ウィジェットを指定します。

次の属性は省略可能です。

  • ignoreChildren - true に設定すると、Robo は無視される UI ウィジェットのすべての子孫も無視します。デフォルトでは false になっています。

以下に、コンテンツの説明が "Avatar" で始まるすべての要素を無視する Robo スクリプト アクションの例を示します。

{
  "eventType": "ELEMENT_IGNORED",
  "elementDescriptors": [
    {
      "contentDescriptionRegex": "Avatar.*"
    }
  ]
}

テキストを入力する

次の表に、必要な属性を示します。

属性 説明
eventType Robo スクリプト アクションのタイプを指定します。
"eventType": "VIEW_TEXT_CHANGED" 指定されたテキストをターゲット UI ウィジェットに入力します。
"eventType": "ENTER_TEXT" 指定されたテキストをターゲット UI ウィジェットに入力してから、この UI ウィジェットに KEYCODE_ENTER イベントを送信します。
elementDescriptors Android UI 階層を使用して、ターゲット UI ウィジェットを識別します。
replacementText ターゲット UI ウィジェットに入力するテキスト。

以下に、リソース ID が "com.google.samples.apps.topeka:id/first_name" の UI ウィジェットに "John" を入力する Robo スクリプト アクションの例を示します。

{
  "eventType": "VIEW_TEXT_CHANGED",
  "replacementText": "John",
  "elementDescriptors": [
    {
      "resourceId": "com.google.samples.apps.topeka:id/first_name"
    }
  ]
}

長押し

次の表に、必要な属性を示します。

属性 説明
"eventType": "VIEW_LONG_CLICKED" --
elementDescriptors Android UI 階層を使用して、ターゲット UI ウィジェットを識別します。 visionText とは相互に排他的です。
visionText OCR を使用して、長押しクリックされた要素を識別します。elementDescriptors とは相互に排他的です。

次の属性は省略可能です。

  • delayTime - 長押しの時間をミリ秒単位で指定します。

次は、コンテンツの説明が "Avatar 8" の UI ウィジェットを 5 秒間長押しする Robo スクリプト アクションの例を示しています。

{
  "eventType": "VIEW_LONG_CLICKED",
  "elementDescriptors": [
    {
      "contentDescription": "Avatar 8"
    }
  ],
  "delayTime": 5000
}

1 ポイント ジェスチャーを実行する

次の表に、必要な属性を示します。

属性 説明
"eventType": "ONE_POINT_GESTURE" --
coordinates 1 ポイント ジェスチャーの 2 つの座標。「(x1,y1)->(x2,y2)」の形式でパーセンテージまたはピクセルを指定します。

次の属性は省略可能です。

  • dragAndDrop - true に設定すると、1 ポイント ジェスチャーによりドラッグ&ドロップ アクションが実行されます。デフォルトでは false になっています。

以下は、下にスワイプする Robo スクリプトの 1 ポイント ジェスチャー アクションの例です。

{
  "eventType": "ONE_POINT_GESTURE",
  "coordinates": "(50%,25%)->(50%,75%)"
}

2 ポイント ジェスチャーを実行する

次の表に、必要な属性を示します。

属性 説明
"eventType": "TWO_POINT_GESTURE" --
coordinates 2 ポイント ジェスチャーの 4 つの座標。「(x1,y1)->(x2,y2),(x3,y3)->(x4,y4)」の形式でパーセンテージまたはピクセルを指定します。

ピンチアウト ジェスチャーを行う Robo スクリプト アクションの例を次に示します。

{
  "eventType": "TWO_POINT_GESTURE",
  "coordinates": "(50%,50%)->(25%,50%),(50%,50%)->(75%,50%)"
}

IME アクションを実行する

このアクションは、指定されたターゲット UI ウィジェットのインプット メソッド エディタ(IME)で、現在のアクション ボタン(「次へ」、「完了」、「検索」など)を押します。

次の表に、必要な属性を示します。

属性 説明
"eventType": "PRESSED_EDITOR_ACTION" --
elementDescriptors Android UI 階層を使用して、ターゲット UI ウィジェットを識別します。

以下に、リソース ID が "com.google.samples.apps.topeka:id/first_name" の UI ウィジェットで IME アクションを実行する Robo スクリプト アクションの例を示します。

{
  "eventType": "PRESSED_EDITOR_ACTION",
  "elementDescriptors": [
    {
      "resourceId": "com.google.samples.apps.topeka:id/first_name"
    }
  ]
}

戻るボタンを押す

次の表に、必要な属性を示します。

属性 説明
eventType Robo スクリプト アクションのタイプを指定します。
"eventType": "PRESSED_BACK" KEYCODE_BACK イベントをデバイスに送信します。
"eventType": "PRESSED_BACK_EMULATOR_28" Android Studio の Robo スクリプト レコーダーが使用して、エミュレータ API 28 で戻るボタンを押します。

戻るボタンを押す Robo スクリプト アクションの例を次に示します。

{
  "eventType": "PRESSED_BACK"
}

ホームボタンを押す

このアクションにより、デバイスへ KEYCODE_HOME イベントが送信されます。

次の表に、必要な属性を示します。

属性 説明
"eventType": "GO_HOME" --

ホームボタンを押す Robo スクリプト アクションの例を次に示します。

{
  "eventType": "GO_HOME"
}

要素をスクロールして表示する

このアクションにより、Robo テストは、指定された childElementDescriptors に一致する UI ウィジェットが画面に表示されるか、スクロールされたウィジェットがスクロールできなくなるか、または最大スクロール数が 50 に達するまで、指定された elementDescriptors に一致する UI ウィジェットを前方にスクロールします。

次の表に、必要な属性を示します。

属性 説明
"eventType": "ELEMENT_SCROLL_INTO_VIEW" --
elementDescriptors Android UI 階層を使用して、スクロールされた UI ウィジェットを識別します。
childElementDescriptors Android UI 階層を使用してスクロールする UI ウィジェットを特定します。

次の例では、テキスト "Orange" の UI ウィジェットが画面に表示されるまで(またはそれ以上スクロールできなくなるか、最大スクロール回数が 50 回に達するまで)、リソース ID が "my.app.package:id/scrollable_card_container" の UI ウィジェットをスクロールします。

{
  "eventType": "ELEMENT_SCROLL_INTO_VIEW",
  "elementDescriptors": [
    {
      "resourceId": "my.app.package:id/scrollable_card_container"
    }
  ],
  "childElementDescriptors": [
    {
      "text": "Orange"
    }
  ]
}

スワイプ

次の表に、必要な属性を示します。

属性 説明
"eventType": "VIEW_SWIPED" --
swipeDirection スワイプの方向を指定します。
  • Left
  • Right
  • Up
  • Down
  • Forward - ターゲット UI ウィジェットの垂直スクロールまたは水平スクロールに応じて、Down または Right になります。
  • Backward - ターゲット UI ウィジェットの垂直スクロールまたは水平スクロールに応じて、Up または Left になります。
elementDescriptors Android UI 階層を使用して、ターゲット UI ウィジェットを識別します。

次に、リソース ID が "my.app.package:id/custom_content" の UI ウィジェットを上にスワイプする Robo スクリプト アクションの例を示します。

{
  "eventType": "VIEW_SWIPED",
  "swipeDirection": "Up",
  "elementDescriptors": [
    {
      "resourceId": "my.app.package:id/custom_content"
    }
  ]
}

スクリーンショットを撮る

次の表に、必要な属性を示します。

属性 説明
"eventType": "TAKE_SCREENSHOT" --
screenshotName スクリーンショットのファイル名を指定します。

スクリーンショットを撮る Robo スクリプト アクションの例を次に示します。

{
  "eventType": "TAKE_SCREENSHOT",
  "screenshotName": "my_screenshot"
}

画面上のポイントをタップする

次の表に、必要な属性を示します。

属性 説明
"eventType": "POINT_TAP" --
pointTapXCoordinate タップされるポイントのピクセル X 座標。pointTapXPercentpointTapYPercent は相互に排他的です。
pointTapYCoordinate タップされるポイントのピクセル Y 座標です。pointTapXPercentpointTapYPercent は相互に排他的です。
pointTapXPercent タップされるポイントのパーセンテージ X 座標。pointTapXCoordinatepointTapYCoordinate は相互に排他的です。
pointTapYPercent タップされるポイントのパーセンテージ Y 座標。pointTapXCoordinatepointTapYCoordinate は相互に排他的です。

画面中央をタップする Robo スクリプト アクションの例を次に示します。

{
  "eventType": "POINT_TAP",
  "pointTapXPercent": 50,
  "pointTapYPercent": 50
}

要素内のポイントをタップする

次の表に、必要な属性を示します。

属性 説明
"eventType": "POINT_TAP_ELEMENT" --
pointTapXPercent ターゲット要素内のパーセンテージ X 座標。
pointTapYPercent ターゲット要素内のパーセンテージ Y 座標。
elementDescriptors Android UI 階層を使用して、ターゲット UI ウィジェットを識別します。

シークバーのスライダーを右に移動する Robo スクリプト アクションの例を次に示します。

{
  "eventType": "POINT_TAP_ELEMENT",
  "pointTapXPercent": 80,
  "pointTapYPercent": 50,
  "elementDescriptors": [
    {
      "resourceId": "my.app.package:id/my_seekbar"
    }
  ]
}

クロールを終了する

このアクションにより、Robo テストが停止します。

次の表に、必要な属性を示します。

属性 説明
"eventType": "TERMINATE_CRAWL" --

Robo テストを停止する Robo スクリプト アクションの例を次に示します。

{
  "eventType": "TERMINATE_CRAWL"
}

待機

次の表に、必要な属性を示します。

属性 説明
"eventType": "DELAYED_MESSAGE_POSTED" --
delayTime 待機時間をミリ秒単位で指定します。

3 秒待機する Robo スクリプト アクションの例を次に示します。

{
  "eventType": "DELAYED_MESSAGE_POSTED",
  "delayTime": 3000
}

要素を待機する

このアクションは、指定されたタイムアウトまでに要素が画面に表示されるまで Robo テストを待機させます。

次の表に、必要な属性を示します。

属性 説明
"eventType": "WAIT_FOR_ELEMENT" --
delayTime 待機タイムアウトをミリ秒単位で指定します。
elementDescriptors Android UI 階層を使用して、待機中の UI ウィジェットを識別します。

次に、リソース ID "my.app.package:id/confirmation_button" の UI ウィジェットが画面に表示されるまで、最大 30 秒間待機する Robo スクリプト アクションの例を示します。

{
  "eventType": "WAIT_FOR_ELEMENT",
  "delayTime": 30000,
  "elementDescriptors": [
    {
      "resourceId": "my.app.package:id/confirmation_button"
    }
  ]
}

次のステップ