本文件提供有關 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 指令碼指派唯一的 id ,其值為 1000 以上,以免發生任何衝突。 |
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 或 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 小工具。可與 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"
}
]
}
]
}
以下是 Robo 指令碼範例,由光學字元辨識 (OCR) 偵測到的 "Privacy Policy"
觸發:
{
"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
|
指定等待時間長度 (以毫秒為單位)。等待動作必填。 |
pointTapXCoordinate 和 pointTapYCoordinate
|
輕觸點的 X 和 Y 像素座標。與 pointTapXPercent 和 pointTapYPercent 互斥。點按點的動作時為必填。 |
pointTapXPercent 和 pointTapYPercent
|
點選點的 X 和 Y 座標百分比。與 pointTapXCoordinate 和 pointTapYCoordinate 互斥。點按點的動作時為必填。 |
以下是 Robo 指令碼範例,其中包含兩個沒有指定 UI 小工具的動作,也就是說,這些動作不會在特定 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 規則運算式。 |
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": "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 指令碼動作的目標 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 指令碼的執行priority
都相同,為1
)。 - 如果 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 會依序觸發下列動作:
"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": "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_IGNORED
和 ALL_ELEMENTS_IGNORED
分別代表的「動作」呈現,並予以忽略。
只要含有忽略動作的 Robo 指令碼的 contextDescriptor
屬性與特定畫面相符,Robo 就不會與任何目標為忽略動作的 UI 小工具互動 (除非其他 Robo 指令碼動作會讓 Robo 對其中一個忽略的 UI 小工具執行動作)。
Robo 指令碼可同時包含忽略、條件和非條件動作。與其他 Robo 指令碼動作不同,只要在 Robo 檢索期間,包含 Robo 指令碼的 contextDescriptor
與螢幕相符,系統就會套用忽略動作,無論 priority
和 maxNumberOfRuns
屬性的值為何。
以下是含有兩個 Robo 指令碼的檔案範例。第一個 Robo 指令碼會讓 Robo 忽略畫面上所有 UI 小工具,其中包含資源 ID "my.app.package:id/ignored_screen"
的 UI 小工具。第二個 Robo 指令碼會讓 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 指令碼會擷取 recyclerViewChildPosition
中,以 Robo 指令碼動作為目標的 RecyclerView 子項的絕對資料位置。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 。 |
以下是點按資源 ID "com.google.samples.apps.topeka:id/done"
的按鈕的 Robo 指令碼動作範例:
{
"eventType": "VIEW_CLICKED",
"elementDescriptors": [
{
"resourceId": "com.google.samples.apps.topeka:id/done"
}
]
}
以下是 Robo 指令碼動作範例,會在使用 OCR 偵測到畫面上第二次出現的 "Search"
字詞上點選:
{
"eventType": "VIEW_CLICKED",
"visionText": "Search",
"matchIndex": 1
}
以下是點選含有內容說明 "Emoji button"
的軟體鍵盤元素的 Robo 指令碼動作範例:
{
"eventType": "SOFT_KEYBOARD_CLICK",
"elementDescriptors": [
{
"contentDescription": "Emoji button"
}
]
}
以下是點選隨機軟體鍵盤元素最多五次的 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 互斥。 |
matchIndex
|
指定使用 visionText 識別目標元素時,相符目標元素出現的索引。如果是 0 ,Robo 指令碼動作會選取第一個符合的元素;如果是 1 ,Robo 指令碼動作會選取第二個符合的元素,依此類推。排序順序是從左至右、由上至下。預設值為 0 (會選取第一個相符項目)。 |
下列屬性為選用項目:
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%)"
}
執行 IME 動作
這個動作會按下指定目標 UI 小工具的目前動作按鈕,例如輸入法編輯器 (IME) 中的「下一個」、「完成」和「搜尋」按鈕。
下表列出必要屬性:
屬性 | 說明 |
---|---|
"eventType": "PRESSED_EDITOR_ACTION"
|
-- |
elementDescriptors
|
使用 Android UI 階層識別目標 UI 小工具。 |
以下是 Robo 指令碼動作範例,可在具有資源 ID "com.google.samples.apps.topeka:id/first_name"
的 UI 小工具上執行 IME 動作:
{
"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": "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"
}
]
}