本文檔提供有關 Robo 腳本的參考信息,包括結構、功能、用法、記錄和操作。 Robo 腳本是自動執行移動應用程序手動質量保證 (QA) 任務並啟用持續集成 (CI) 和預啟動測試策略的測試。 Robo 腳本是一個 JSON 文件,它描述了一系列用戶界面 (UI) 和其他操作。
您可以通過以下方式創建 Robo 腳本:
- 使用 Robo 腳本錄製功能。
- 手動創建 Robo 腳本。
- 錄製 Robo 腳本,然後手動編輯它。
要了解有關使用 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"
}
]
}
]
結構
Robo 腳本有幾個描述 Robo 如何執行它的屬性。這些屬性中的大多數都是可選的,具有預定義的默認值:
屬性 | 描述 |
id | 有助於在爬網輸出中跟踪此 Robo 腳本的整數。 |
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": "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 測試執行的最後一個動作是否不是 Robo 腳本動作。 |
negateCondition | 如果設置為true ,則否定condition 。例如,您可以使用此屬性來檢查屏幕上是否不存在 UI 小部件,或者被測應用程序是否未在前台運行。 |
elementDescriptors | 一個或多個元素描述符,用於標識屏幕上的 UI 小部件。它與element_present 、 element_disabled 和element_checked 條件結合使用。與visionText 互斥。有關詳細信息,請參閱元素描述符。 |
visionText | 使用光學字符識別 (OCR) API 檢測屏幕上的文本。 visionText 與element_present 條件結合使用。與elementDescriptors 互斥。 |
以下是 Robo 腳本的示例,它由屏幕上顯示資源 ID "my.app.package:id/page_header"
UI 小部件觸發:
{
"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 腳本中的每個動作都表示為一組一個或多個屬性值對,如下表所述:
屬性 | 描述 |
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 腳本作為常規儀器測試執行,一旦無法執行其任何操作,就會失敗。
-
-
postscript
- Robo 腳本完成後應用的執行選項:-
terminate
- 如果設置為true
,Robo 測試將在 Robo 腳本完成後停止爬行。
-
以下是在strict
模式下執行的 Robo 腳本示例,該腳本會休眠三秒鐘,然後停止抓取:
"roboscript": {
"executionMode": {
"strict": true
},
"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 腳本來賦予優先級:
- 具有
contextDescriptor
屬性。 - 具有最高
priority
(默認情況下,所有 Robo 腳本都具有相同的執行priority
1
)。 - 如果 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 按順序觸發以下操作:
-
"Robo script 2"
因為它的優先級最高。 -
"Robo script 1"
,因為它在具有相同優先級的剩餘適用 Robo 腳本中出現得較早。 -
"Robo script 3"
作為最後一個適用的 Robo 腳本。
重複運行
默認情況下,Robo 在抓取過程中最多觸發一次 Robo 腳本。這可以通過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 完成對被測應用程序的抓取後。 |
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 腳本的上下文描述符](#context-descriptor) 相同的結構並提供類似的功能。 |
當被觸發時,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 腳本的contextDescriptor
在 Robo 爬網期間與屏幕匹配,就會應用忽略操作,而不管priority
和maxNumberOfRuns
屬性的值。
以下是包含兩個 Robo 腳本的文件示例。第一個 Robo 腳本使 Robo 忽略屏幕上的所有 UI 小部件,該屏幕包含資源 ID 為"my.app.package:id/ignored_screen"
UI 小部件。第二個 Robo 腳本使 Robo 在包含資源 ID 為"my.app.package:id/main_screen"
".*:id/done"
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 子級的操作按以下步驟執行:
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 測試實驗室,並相應地運行測試。
當您在附加腳本的情況下運行 Robo 測試時,Robo 測試首先執行預先編寫的腳本操作,然後像往常一樣探索應用程序。
要在 Android Studio 中創建 Robo 腳本 JSON 文件,請按照使用 Android Studio 中的測試實驗室錄製 Robo 腳本中的步驟操作。
機器人腳本動作
以下公共可選屬性適用於所有操作:
-
description
- 幫助在 Robo 測試輸出中跟踪此 Robo 腳本操作的執行情況。
斷言
如果斷言條件為真,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 互斥。 |
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 在屏幕上檢測到的"Privacy Policy"
:
{
"eventType": "VIEW_CLICKED",
"visionText": "Privacy Policy"
}
下面是一個 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 調試橋 (adb) shell 命令。 |
以下是清除被測應用用戶數據的 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 小部件。 |
以下是一個 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 小部件中的文本。 |
以下是將"John"
輸入資源 ID 為"com.google.samples.apps.topeka:id/first_name"
的 UI 小部件的 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 小部件。 |
以下屬性是可選的:
-
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%)"
}
執行 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 小部件。 |
以下是向上滑動資源 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 坐標。與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"
}
]
}