本文件提供 Robo 指令碼的參考資訊,包括結構、功能、用途、錄製和動作。Robo 指令碼是自動執行行動應用程式手動品質保證 (QA) 工作的測試,可啟用持續整合 (CI) 和正式發布前測試策略。Robo 指令碼是 JSON 檔案,用於描述使用者介面 (UI) 和其他動作的序列。
您可以透過下列方式建立 Robo 指令碼:
使用 Robo 指令碼錄製功能。(僅限 Android 裝置)
手動建立 Robo 指令碼。(Android 和 iOS+)
錄製 Robo 指令碼,然後手動編輯。(僅限 Android 裝置)
如要進一步瞭解如何使用 Robo 指令碼,請參閱「執行 Robo 指令碼」。
簡介
Robo 指令碼會與其他輸入內容 (例如受測應用程式的 Android 應用程式套件 (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 指令碼,且具有預設的 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 指令碼
Robo for iOS+ (Beta 版) 對 Robo 指令碼的支援有限。iOS+ 的 Robo 指令碼語法與 Android 語法相同,且支援的 iOS+ 功能行為與 Android 類似。
iOS+ 支援下列動作:
- 斷言
- 點按
- 長按
- 滑動
- 忽略所有元素
- 等待
- 擷取螢幕截圖
- 終止檢索
iOS+ 支援元素描述元中的下列識別屬性:
- 課程名稱
- 上層類別名稱
- 內容說明 (和規則運算式)
- 文字 (和規則運算式)
iOS+ 支援下列情境描述元中的觸發條件:
- 顯示受測應用程式
- 元素存在
- 執行非 Robo 指令碼動作
結構
Robo 指令碼有多個屬性,用於描述 Robo 執行指令碼的方式。其中大部分屬性為選用,並預先定義了預設值:
| 屬性 | 說明 |
id
|
一個整數,有助於在檢索輸出內容中追蹤這個 Robo 指令碼。
Robo 內建 Robo 指令碼,並有專屬的 id。雖然不同 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_present、element_disabled 和 element_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" : "WAIT",
"delayTime" : 5000
}]
}
動作
Robo 指令碼中的每個動作都會以一或多個屬性值組合的形式呈現,如下表所述:
| 屬性 | 說明 |
eventType
|
指定動作類型,例如點擊、文字編輯等。每項動作都必須指定。 |
elementDescriptors
|
用於識別 UI 小工具的描述元。凡是具有目標 UI 小工具的所有動作 (例如點選特定按鈕),都必須提供這項資訊。 |
optional
|
如果設為 true,系統會在無法執行這項動作時略過。舉例來說,如果這項動作在畫面上找不到目標 UI 小工具,系統就會略過這項動作,而不會導致包含這項動作的 Robo 指令碼失敗。預設值為 false。 |
replacementText
|
要輸入目標 UI 小工具的文字。文字編輯動作的必要項目。 |
swipeDirection
|
指定滑動方向。滑動動作必須使用。 |
delayTime
|
指定等待時間 (以毫秒為單位)。等待動作的必要欄位。 |
pointTapXCoordinate 和 pointTapYCoordinate
|
輕觸點的像素 X 和 Y 座標。與 pointTapXPercent 和 pointTapYPercent 互斥。點按動作必須提供。 |
pointTapXPercent 和 pointTapYPercent
|
輕觸點的 X 和 Y 座標百分比。與 pointTapXCoordinate 和 pointTapYCoordinate 互斥。點按動作必須提供。
|
以下範例 Robo 指令碼包含兩個動作,但沒有目標 UI 小工具,也就是說,這些動作不會在特定 UI 小工具上執行:
[
{
"eventType": "WAIT",
"delayTime": 3000
},
{
"eventType": "PRESSED_BACK"
}
]
元素描述元
元素描述元會使用下列一或多個識別屬性,識別 UI 小工具:
| 屬性 | 說明 |
className
|
– |
ancestorClassName
|
元素 UI 階層祖系的類別名稱。祖系是指元素 UI 階層中的任何父項節點,包括元素本身。 |
resourceId
|
– |
resourceIdRegex
|
用於比對 resourceId 的 Java 規則運算式。 |
contentDescription
|
– |
contentDescriptionRegex
|
用於比對 contentDescription 的 Java 規則運算式。 |
text (顯示在畫面上)
|
– |
textRegex
|
用於比對 text 的 Java 規則運算式。 |
groupViewChildPosition、recyclerViewChildPosition 或 adapterViewChildPosition
|
代表 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 指令碼的動作清單前加上 JSON 物件,指定該 Robo 指令碼的執行選項。這個設定標頭以 roboscript 關鍵字開頭,後面接著所需執行選項的 JSON 表示法。
Robo 指令碼支援下列執行選項:
executionMode- 執行 Robo 指令碼時套用的執行選項:strict:如果設為true,Robo 指令碼不會採用部分比對、略過目前動作和暫停。也就是說,Robo 指令碼會以一般檢測設備測試的形式執行,只要有任何動作無法執行,就會失敗。預設值為false。dismiss_popups:如果設為true,Robo 測試在執行 Robo 指令碼時,會關閉任何非預期的對話方塊,即使在strict模式下也一樣。如果不在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": "WAIT",
"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 指令碼動作的目標 UI 小工具時,部分比對不會考量最外層的元素描述元。 如果部分比對成功,系統會照常執行對應的 Robo 指令碼動作。這項技術支援應用程式結構變更的情境,例如在應用程式版本之間重新排列畫面元素。 |
| 略過目前的動作 | 如果目前的 Robo 指令碼動作無法完全或部分比對,Robo 會嘗試比對後續的 Robo 指令碼動作。如果後續動作完全或部分相符,Robo 測試會略過目前的 Robo 指令碼動作 (且不會返回),並執行後續動作。 這項技術支援應用程式行為在不同版本之間變更或不穩定的情況,例如在錄製與重播 Robo 指令碼期間,間歇性對話方塊可能會出現在不同畫面上。 |
| 暫停 | 如果目前和後續的 Robo 指令碼動作都無法完全或部分比對,Robo 指令碼會暫時停用,Robo 測試則會使用其他策略選擇要執行的動作。完成這項動作後,Robo 測試會繼續執行 Robo 指令碼。 只要目前或後續的 Robo 指令碼動作無法比對,Robo 指令碼就會維持暫停狀態,無論動作數量為何。因此,Robo 指令碼不一定要是 Robo 測試的前置作業,您可以在標準 Robo 測試動作中穿插 Robo 指令碼動作。如果應用程式行為不穩定,或應用程式版本之間的變更幅度過大,Robo 測試需要透過標準動作「填補差距」,這項技術就適用於這類情境。 |
優先順序
如果 Robo 指令碼達到maxNumberOfRuns,就無法在特定檢索中觸發。如果目前情境可觸發多個 Robo 指令碼,系統會按照下列順序選擇 Robo 指令碼:
- 具有
contextDescriptor屬性。 - 具有最高
priority(根據預設,所有 Robo 指令碼都具有相同的1執行priority)。 - 如果 Robo 指令碼的優先順序相同,則會顯示在 Robo 指令碼清單的最前面。
以下範例檔案包含三個 Robo 指令碼,這些指令碼會執行相同動作,並由相同條件觸發:受測應用程式位於前景:
[
{
"id": 1000,
"description": "Robo script 1",
"contextDescriptor": {
"condition": "app_under_test_shown"
},
"actions": [
{
"eventType": "WAIT",
"delayTime": 3000
}
]
},
{
"id": 1001,
"description": "Robo script 2",
"priority": "2",
"contextDescriptor": {
"condition": "app_under_test_shown"
},
"actions": [
{
"eventType": "WAIT",
"delayTime": 3000
}
]
},
{
"id": 1002,
"description": "Robo script 3",
"contextDescriptor": {
"condition": "app_under_test_shown"
},
"actions": [
{
"eventType": "WAIT",
"delayTime": 3000
}
]
}
]
當受測應用程式位於前景時,Robo 會依序觸發下列動作:
"Robo script 2",因為其優先順序最高。"Robo script 1",因為在剩餘適用且優先順序相同的 Robo 指令碼中,該指令碼較早出現。"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 完成對受測應用程式的檢索後。post_crawl Robo 指令碼的時間長度不得超過 15 秒,否則檢索作業可能會因逾時而終止。 |
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": "WAIT",
"delayTime": 10000
},
{
"description": "Screen on",
"eventType": "ADB_SHELL_COMMAND",
"command": "input keyevent 82"
},
{
"description": "Wait for 10 seconds",
"eventType": "WAIT",
"delayTime": 10000
}
}
忽略動作
Robo 指令碼可以包含指示,讓 Robo 忽略特定 UI 小工具,或特定畫面上的所有 UI 小工具。這些指令會以忽略「動作」的形式呈現,並分別對應 eventType、ELEMENT_IGNORED 和 ALL_ELEMENTS_IGNORED。
只要 Robo 指令碼的 contextDescriptor 屬性包含忽略動作,且與指定畫面相符,Robo 就不會與忽略動作指定的任何 UI 小工具互動 (除非其他 Robo 指令碼動作讓 Robo 對其中一個忽略的 UI 小工具執行動作)。
Robo 指令碼可以包含忽略、條件式和非條件式動作。與其他 Robo 指令碼動作不同,只要 Robo 指令碼的 contextDescriptor 與 Robo 檢索期間的畫面相符,系統就會套用忽略動作,無論 priority 和 maxNumberOfRuns 屬性的值為何。
以下是包含兩個 Robo 指令碼的檔案範例。第一個 Robo 指令碼會讓 Robo 忽略畫面上包含資源 ID "my.app.package:id/ignored_screen" 的 UI 小工具的所有 UI 小工具。第二個 Robo 指令碼會讓 Robo 忽略 UI 小工具,其資源 ID 與 Java 規則運算式 ".*:id/done" 相符,且畫面包含資源 ID 為 "my.app.package:id/main_screen" 的 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 指令碼也會擷取 AdapterView 子項的絕對資料位置,這些子項是 Robo 指令碼動作的目標,例如 adapterViewChildPosition。
對 RecyclerView 和 AdapterView 子項執行的動作會按照下列步驟執行:
Robo 測試會透過對包含 RecyclerView 或 AdapterView 的定位動作,確保對應的子項顯示在畫面上。
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"
|
點按待測應用程式的目標元素。 |
"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 互斥。 |
matchIndex
|
使用 visionText 識別目標元素時,指定相符目標元素出現的索引。如果為 0,Robo 指令碼動作會挑選第一個相符元素;如果為 1,Robo 指令碼動作會挑選第二個相符元素,依此類推。順序是由左至右、由上至下。預設值為 0 (系統會挑選第一個相符項目)。 |
maxNumberOfRuns
|
指定當 eventType 為 SOFT_KEYBOARD_RANDOM_CLICK 時,點擊螢幕鍵盤隨機元素的次數。預設值為 1。
|
以下是 Robo 指令碼動作範例,會點選資源 ID 為 "com.google.samples.apps.topeka:id/done" 的按鈕:
{
"eventType": "VIEW_CLICKED",
"elementDescriptors": [
{
"resourceId": "com.google.samples.apps.topeka:id/done"
}
]
}
以下範例說明 Robo 指令碼動作,該動作會使用 OCR 點選畫面上偵測到的第二個 "Search" 字詞:
{
"eventType": "VIEW_CLICKED",
"visionText": "Search",
"matchIndex": 1
}
以下是 Robo 指令碼動作範例,可點選內容說明為 "Emoji button" 的軟鍵盤元素:
{
"eventType": "SOFT_KEYBOARD_CLICK",
"elementDescriptors": [
{
"contentDescription": "Emoji button"
}
]
}
以下是 Robo 指令碼動作範例,可隨機點擊軟鍵盤元素最多五次:
{
"eventType": "SOFT_KEYBOARD_RANDOM_CLICK",
"maxNumberOfRuns": 5
}
停用螢幕鍵盤
下表列出必要屬性:
| 屬性 | 說明 |
"eventType": "DISABLE_KEYBOARD"
|
-- |
以下是停用軟鍵盤的 Robo 指令碼動作範例:
{
"eventType": "DISABLE_KEYBOARD"
}
執行 adb shell 指令
下表列出必要屬性:
| 屬性 | 說明 |
"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 互斥。 |
matchIndex
|
使用 visionText 識別目標元素時,指定相符目標元素出現的索引。如果為 0,Robo 指令碼動作會挑選第一個相符元素;如果為 1,Robo 指令碼動作會挑選第二個相符元素,依此類推。順序是由左至右、由上至下。預設值為 0 (系統會挑選第一個相符項目)。 |
選用屬性如下:
delayTime:指定長按動作的持續時間,以毫秒為單位。
以下範例 Robo 指令碼動作會對內容說明為 "Avatar 8" 的 UI 小工具執行五秒長的點擊:
{
"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) 上的目前動作按鈕,例如「下一步」、「完成」和「搜尋」。
下表列出必要屬性:
| 屬性 | 說明 |
|---|---|
"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
|
指定滑動方向:
|
elementDescriptors
|
使用 Android UI 階層識別目標 UI 小工具。 |
以下是 Robo 指令碼動作範例,可向上滑動資源 ID 為 "my.app.package:id/custom_content" 的 UI 小工具:
{
"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 座標。與 pointTapXPercent 和 pointTapYPercent 互斥。 |
pointTapYCoordinate
|
輕觸點的像素 Y 座標。與 pointTapXPercent 和 pointTapYPercent 互斥。 |
pointTapXPercent
|
輕觸點的 X 座標百分比。與 pointTapXCoordinate 和 pointTapYCoordinate 互斥。 |
pointTapYPercent
|
輕觸點的 Y 座標百分比。與 pointTapXCoordinate 和 pointTapYCoordinate 互斥。 |
以下是 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": "WAIT" (or "DELAYED_MESSAGE_POSTED")
|
-- |
delayTime
|
指定等待時間長度 (以毫秒為單位)。 |
以下是等待三秒的 Robo 指令碼動作範例:
{
"eventType": "WAIT",
"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"
}
]
}