Robo 指令碼參考指南

本文件提供 Robo 指令碼的參考資訊,包括結構、功能、使用、記錄和動作。Robo 指令碼是一種測試,可自動處理行動應用程式的手動品質確保 (QA) 工作,並啟用持續整合 (CI) 和正式發布前測試策略。Robo 指令碼是 JSON 檔案,用於說明一系列使用者介面 (UI) 和其他動作。

您可以按照下列方式建立 Robo 指令碼:

  • 使用 Robo 指令碼錄製功能。(僅限 Android 裝置)

  • 手動建立 Robo 指令碼。(Android 和 iOS 以上版本)

  • 錄製 Robo 指令碼,然後手動編輯。(僅限 Android 裝置)

如要進一步瞭解如何使用 Robo 指令碼,請參閱「執行 Robo 指令碼」。

引言

Robo 指令碼會提供給 Robo 測試與其他輸入內容,例如應用程式背後測試的 Android 應用程式套件 (APK)。

以下是會在應用程式下測啟動時觸發的 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 指令碼,並且具有預設的 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"
      }
    ]
  }
]

iOS+ 支援 Robo 指令碼

適用於 iOS+ (Beta 版) 的 Robo (Beta 版) 僅對 Robo 指令碼提供有限支援。iOS+ 的 Robo 指令碼語法與 Android 語法相同,且支援的 iOS+ 功能行為與 Android 對應功能類似。

iOS+ 支援下列動作:

  • 斷言
  • 點按
  • 長按
  • 滑動
  • 忽略所有元素
  • 等待
  • 擷取螢幕截圖
  • 終止檢索

iOS+ 支援下列元素描述元中的下列識別屬性:

  • 類別名稱
  • 祖系類別名稱
  • 內容說明 (和規則運算式)
  • 文字 (和規則運算式)

iOS+ 支援下列情境描述元中的觸發條件

  • 已顯示測試中的應用程式
  • 有元素
  • 已執行非 Robo 指令碼動作

結構

Robo 指令碼有幾項屬性,說明 Robo 的執行方式。這些屬性大多為選用,並具有預先定義的預設值:

屬性 說明
id 一個整數編號,有助於在檢索輸出中追蹤這個 Robo 指令碼。Robo 內建有自己的 id 的 Robo 指令碼。雖然不同 Robo 指令碼中的相同 id 不會影響其行為,但在檢索輸出內容中區分動作和這些 Robo 指令碼可能並不容易。建議您為 Robo 指令碼指派 1000 以上的不重複 id,以免發生衝突。
description id 類似,但較為描述性。
crawlStage 檢索 Robo 的階段會在 執行這個 Robo 指令碼。根據預設,這會是主要的檢索階段。
priority 與其他 Robo 指令碼相比,這個 Robo 指令碼的優先順序。根據預設,所有 Robo 指令碼的優先順序都是 1
maxNumberOfRuns 指定檢索 Robo 可執行這個 Robo 指令碼的次數。根據預設,Robo 可以執行一次 Robo 指令碼。
contextDescriptor 說明觸發這個 Robo 指令碼的情境或條件。如果省略此旗標,系統會視為一律符合此 Robo 指令碼的觸發條件;換句話說,Robo 指令碼並無條件。
actions 這個 Robo 指令碼的所有動作。

單一檔案內含一或多個 Robo 指令碼。

以下範例檔案包含兩個無條件的 Robo 指令碼,每個指令碼都包含單一動作,在檢索開始時只會執行一次:

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

情境描述元

結構定義描述元使用一或多個屬性定義觸發 Robo 指令碼的情境或條件:

屬性 說明
"condition": "always" 一律觸發 Robo 指令碼。
"condition": "element_present" 檢查螢幕上是否出現與 elementDescriptors 相符的 UI 小工具,或 visionText 指定的文字。
"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 小工具的一或多個元素描述元。此變數會與 element_presentelement_disabledelement_checked 條件搭配使用。與 visionText 互斥。詳情請參閱「元素描述元」。
visionText 系統會使用光學字元辨識 (OCR) API 偵測畫面上的文字。visionText 會與 element_present 條件搭配使用。與 elementDescriptors 互斥。
nonRoboscriptActionCount 先前連續執行的非 Robo 指令碼動作數量。此限定詞會與 non_roboscript_action_performed 條件搭配使用,以在每次 nonRoboscriptActionCount Robo 動作後觸發 Robo 指令碼。預設值為 1

以下範例中的 Robo 指令碼範例是由 UI 小工具觸發,且螢幕上顯示資源 ID "my.app.package:id/page_header"

{
  "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 指令碼的範例,每個非指令碼的 Robo 動作都會等待 5 秒:

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

動作

Robo 指令碼中的每項動作都會以一或多個屬性/值組合的組合表示,詳情請見下表:

屬性 說明
eventType 指定動作類型,例如點擊、文字編輯等。每個動作都必須具備。
elementDescriptors 用於識別 UI 小工具的描述元。所有包含目標 UI 小工具的動作 (例如點選特定按鈕) 都必須完成必要操作。
optional 如果設為 true,系統會在無法執行時略過這個動作。舉例來說,如果在畫面上找不到目標 UI 小工具,系統會略過這個動作,而不會失敗包含的 Robo 指令碼。根據預設,這個值為 false
replacementText 要輸入至目標 UI 小工具的文字。這是文字編輯動作的必要欄位。
swipeDirection 指定滑動方向。滑動動作則為必要項目。
delayTime 指定等待時間長度 (以毫秒為單位)。等待動作的必要項目。
pointTapXCoordinatepointTapYCoordinate 觸碰點的像素 X 和 Y 座標。與 pointTapXPercentpointTapYPercent 互斥。點輕觸動作時為必要項目。
pointTapXPercentpointTapYPercent 可輕觸點的百分比 X 和 Y 座標。與 pointTapXCoordinatepointTapYCoordinate 互斥。點輕觸動作時為必要項目。

以下是含有兩項動作但沒有目標 UI 小工具的 Robo 指令碼範例,也就是說,這些動作不會在特定的 UI 小工具上運作:

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

元素描述元

元素描述元會使用下列一或多個識別屬性來識別 UI 小工具:

屬性 說明
className
ancestorClassName 元素的 UI 階層祖系類別名稱。祖係是元素 UI 階層中的任何父項節點,包括元素本身。
resourceId
resourceIdRegex 用於比對 resourceId 的 Java 規則運算式。
contentDescription
contentDescriptionRegex 用於比對 contentDescription 的 Java 規則運算式。
text (顯示在螢幕上)
textRegex 用於比對 text 的 Java 規則運算式。
groupViewChildPositionrecyclerViewChildPositionadapterViewChildPosition 代表 UI 小工具的子項位置 (視其父項小工具類型而定)。

這些屬性通常未定義,例如按鈕可能沒有文字和內容說明。即使有某些屬性值,在特定應用程式畫面上 (包括 resourceId) 上也可能重複。

舉例來說,如要區分清單項目,通常只有在父項小工具內使用其不同的子項位置。也就是說,只使用一個元素描述元來識別 UI 小工具通常並不足夠。因此,動作的 elementDescriptors 屬性包含一系列元素描述元經過排序的順序,讓第一個元素對應至目標 UI 小工具,第二個則對應至目標 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 指令碼,Robo 測試仍會關閉任何非預期的對話方塊。在非 strict 模式下,這個選項不會有任何作用。預設為 false
    • notify:如果設為 false,Robo 指令碼就不會在執行作業開始和結束時顯示畫面上的通知。預設值為 true
  • postscript - 完成 Robo 指令碼後套用的執行選項:
    • terminate:如果設為 true,Robo 測試會在 Robo 指令碼完成後停止檢索。預設值為 false

以下範例說明在 strict 模式下執行的 Robo 指令碼,沒有在畫面上顯示通知三秒後停止顯示通知,之後檢索會停止:

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

範本參數

範本參數是 Robo 指令碼中的預留位置,當 Robo 測試載入用於執行的 Robo 指令碼時,該值會替換為實際值。範本參數的前置字串是雙底線,後面接著百分比符號,後接百分比符號後接雙底線。

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 指令碼清單中。

以下範例檔案包含三個 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 指令碼。

重複執行

根據預設,在檢索期間,Robo 最多會觸發 Robo 指令碼。您可以透過 maxNumberOfRuns 屬性進行調整。

以下 Robo 指令碼示例將進行應用程式背後測試的作業傳入背景 10 次:

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

檢索階段

Robo 指令碼適用於特定 Robo 檢索的各個階段:

檢索階段 說明
pre_crawl Robo 啟動並開始檢索該應用程式前,已經開始檢索。
post_crawl Robo 完成應用程式之下測試後。
crawl 主要的檢索階段,也就是 Robo 檢索應用程式之下測試時的情況。
close_screen 當 Robo 嘗試從特定畫面返回 (返回) 時,系統會在探索這個畫面上所有可能的動作時。根據預設,Robo 會按下返回按鈕,因此在某些情況下不適合使用。

如果未指定 Robo 指令碼的 crawlStage 屬性,則其隱含為 crawl

以下的 Robo 指令碼範例會在 Robo 開始檢索之前,清除應用程式底下的測試使用者資料:

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

以下示範如何在 Robo 指令碼中,在每次嘗試從確認對話方塊返回 (返回) 時指示 Robo 點選 "Cancel"

{
  "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 如何執行這些屬性:

屬性 說明
priority 與其他條件式動作中含有 Robo 指令碼的其他條件式動作相比,這項條件動作的優先順序。根據預設,所有條件式動作的優先順序為 1
maxNumberOfRuns 在執行含有 Robo 指令碼的程序期間,可執行幾次條件動作。根據預設,所有條件式動作一次最多可以執行一次,且該動作包含 Robo 指令碼。
contextDescriptor 觸發這項條件動作的情境/條件。這個指令碼的結構相同,提供的功能與 Robo 指令碼的 contextDescriptor 類似

觸發後,Robo 指令碼會逐一執行非條件式操作,並依照顯示順序逐一執行。如果 Robo 指令碼包含條件式動作,系統會在每次挑選非條件式動作前,先考量這些動作。如果根據優先順序和剩餘的執行次數,觸發並選擇任何條件動作,Robo 指令碼就會執行此條件動作。否則,Robo 指令碼會執行下列非條件動作。Robo 指令碼必須包含至少一個非條件動作,才算有效。

以下是沒有條件式 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 指令碼可包含指示,讓 Robo 忽略特定 UI 小工具或特定畫面上所有 UI 小工具。這些操作說明分別表示忽略 eventType ELEMENT_IGNOREDALL_ELEMENTS_IGNORED 的「actions」。

每當含有忽略動作的 Robo 指令碼的 contextDescriptor 屬性與特定畫面相符時,Robo 就不會與忽略動作指定的任何 UI 小工具互動 (除非有其他 Robo 指令碼動作讓 Robo 在其中一個忽略的 UI 小工具上執行動作)。

Robo 指令碼可以包含忽略、條件式和非條件式動作。與其他 Robo 指令碼動作不同,只要動作所包含的 Robo 指令碼的 contextDescriptor 與 Robo 檢索期間的螢幕相符,無論 prioritymaxNumberOfRuns 屬性的值為何,系統才會套用忽略動作。

以下是含有兩個 Robo 指令碼的檔案範例。第一個 Robo 指令碼會讓 Robo 忽略畫面上包含 UI 小工具 (資源 ID 為 "my.app.package:id/ignored_screen") 的所有 UI 小工具。第二個 Robo 指令碼會讓 Robo 忽略資源 ID 與 Java 規則運算式 ".*:id/done" 相符的 UI 小工具,這些小工具所在的畫麵包含 UI 小工具 (資源 ID 為 "my.app.package:id/main_screen"):

[
  {
    "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 指令碼會繼續執行下一個動作,可能是另一個斷言。否則 Robo 指令碼執行作業會因為斷言失敗而停止執行。

下表列出必要屬性:

屬性 說明
"eventType": "ASSERTION" --
contextDescriptor 說明斷言的情境或狀況。兩者的結構相同,並提供與 Robo 指令碼的 contextDescriptor 類似的功能。

以下是 Robo 指令碼斷言的範例,用於檢查應用程式進行的測試是否在前景:

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

以下 Robo 指令碼斷言範例會檢查畫面上是否顯示資源 ID 為 "com.google.samples.apps.topeka:id/done" 的 UI 小工具:

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

以下是 Robo 指令碼斷言的範例,用於透過 OCR 檢查螢幕上「未」偵測到 "Settings"

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

點按

下表列出必要屬性:

屬性 說明
eventType 指定 Robo 指令碼動作的類型。
"eventType": "VIEW_CLICKED" 點按 app-under-test 的目標元素。
"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 指令碼動作的 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%__"
}

授予權限

這項操作由 Android Studio 中的 Robo 指令碼記錄工具記錄,以便與 Espresso Test Recorder 回溯相容。Robo 測試會在每次檢索開始時,將所有權限授予應用程式並進行應用程式測試,因此這項操作屬於免責事項。請勿在 Robo 指令碼中使用這項動作。

下表列出必要屬性:

屬性 說明
"eventType": "PERMISSIONS_REQUEST" --

忽略畫面上的所有元素

這項操作會讓 Robo 忽略任何螢幕上會觸發包含 Robo 指令碼的所有元素。

下表列出必要屬性:

屬性 說明
"eventType": "ALL_ELEMENTS_IGNORED" --

以下範例中的 Robo 指令碼動作範例會讓 Robo 忽略畫面上的所有元素:

{
  "eventType": "ALL_ELEMENTS_IGNORED"
}

忽略元素

這項操作會讓 Robo 忽略符合指定 elementDescriptors 的元素。

下表列出必要屬性:

屬性 說明
"eventType": "ELEMENT_IGNORED" --
elementDescriptors 使用 Android UI 階層找出已忽略的 UI 小工具。

以下為選用屬性:

  • ignoreChildren:如果設為 true,Robo 也會忽略忽略 UI 小工具的所有子系。預設值為 false

以下範例中的 Robo 指令碼動作範例會使 Robo 忽略內容說明開頭為 "Avatar" 的所有元素:

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

輸入文字

下表列出必要屬性:

屬性 說明
eventType 指定 Robo 指令碼動作的類型。
"eventType": "VIEW_TEXT_CHANGED" 將指定文字輸入至目標 UI 小工具。
"eventType": "ENTER_TEXT" 將指定文字輸入目標 UI 小工具,然後傳送 KEYCODE_ENTER 事件到這個 UI 小工具。
elementDescriptors 使用 Android UI 階層識別目標 UI 小工具。
replacementText 要輸入至目標 UI 小工具的文字。

以下是 Robo 指令碼動作的範例,此動作可將 "John" 輸入資源 ID 為 "com.google.samples.apps.topeka:id/first_name" 的 UI 小工具:

{
  "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 - 指定長按的向下長按時間長度,以毫秒為單位。

以下範例中的 Robo 指令碼動作範例會長時間按一下含有內容說明 "Avatar 8" 的 UI 小工具 5 秒:

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

做出單點手勢

下表列出必要屬性:

屬性 說明
"eventType": "ONE_POINT_GESTURE" --
coordinates 單點手勢的兩個座標,格式為「(x1,y1)->(x2,y2)」,以百分比或像素表示。

以下為選用屬性:

  • dragAndDrop:如果設為 true,單點手勢會執行拖曳動作。預設值為 false

以下是執行向下滑動手勢的 Robo 指令碼單點手勢動作範例:

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

做出兩點手勢

下表列出必要屬性:

屬性 說明
"eventType": "TWO_POINT_GESTURE" --
coordinates 兩點手勢的四個座標,格式為「(x1,y1)->(x2,y2),(x3,y3)->(x4,y4)」,以百分比或像素表示。

以下是執行雙指向外手勢的 Robo 指令碼動作範例:

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

執行輸入法編輯器動作

這個動作會在指定目標 UI 小工具的輸入法編輯器 (IME) 上,按下目前的動作按鈕,例如「Next」、「完成」和「搜尋」。

下表列出必要屬性:

屬性 說明
"eventType": "PRESSED_EDITOR_ACTION" --
elementDescriptors 使用 Android UI 階層識別目標 UI 小工具。

以下範例中的 Robo 指令碼動作範例會對資源 ID "com.google.samples.apps.topeka:id/first_name" 的 UI 小工具執行輸入法編輯器動作:

{
  "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 測試將與指定 elementDescriptors 相符的 UI 小工具往前捲動,直到畫面上出現符合指定 childElementDescriptors 的 UI 小工具,或者已捲動的小工具無法再捲動,或達到 50 次的捲動數量上限。

下表列出必要屬性:

屬性 說明
"eventType": "ELEMENT_SCROLL_INTO_VIEW" --
elementDescriptors 使用 Android UI 階層識別捲動式 UI 小工具。
childElementDescriptors 識別使用 Android UI 階層要捲動的 UI 小工具。

以下範例中的 Robo 指令碼動作會捲動含有資源 ID "my.app.package:id/scrollable_card_container" 的 UI 小工具,直到螢幕上顯示文字 "Orange" 的 UI 小工具為止 (否則無法執行更多捲動,或達到 50 次捲動的數量上限):

{
  "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 小工具的垂直或水平捲動性,設定 DownRight
  • Backward - UpLeft,視目標 UI 小工具的垂直或水平捲動性而定。
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 指定等待時間長度 (以毫秒為單位)。

以下是等待三秒的 Robo 指令碼動作範例:

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

等待元素

這項操作會讓 Robo 測試等到元素顯示在畫面上時,才達到指定的逾時時間。

下表列出必要屬性:

屬性 說明
"eventType": "WAIT_FOR_ELEMENT" --
delayTime 指定等待逾時 (以毫秒為單位)。
elementDescriptors 使用 Android UI 階層識別已等待的 UI 小工具。

以下範例中的 Robo 指令碼動作範例等待最多 30 秒,讓包含資源 ID "my.app.package:id/confirmation_button" 的 UI 小工具顯示在螢幕上:

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

後續步驟