Robo 腳本參考指南

本文檔提供有關 Robo 腳本的參考信息,包括結構、功能、用法、記錄和操作。 Robo 腳本是自動執行行動應用程式的手動品質保證 (QA) 任務的測試,並支援持續整合 (CI) 和發布前測試策略。 Robo 腳本是一個 JSON 文件,描述一系列使用者介面 (UI) 和其他操作。

您可以透過以下方式建立 Robo 腳本:

  • 使用 Robo 腳本錄製功能。 (僅限安卓)

  • 手動建立 Robo 腳本。 (安卓和iOS+)

  • 錄製 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"
      }
    ]
  }
]

iOS+ 對 Robo 腳本的支持

iOS+ 版 Robo(測試版)對 Robo 腳本的支援有限。 iOS+ 的 Robo 腳本語法與 Android 語法相同,支援的 iOS+ 功能的行為與 Android 對應功能類似。

iOS+ 支援以下操作:

  • 斷言
  • 點選
  • 長按
  • 滑動
  • 忽略所有元素
  • 等待
  • 截圖
  • 終止抓取

iOS+ 支援元素描述符中的以下標識屬性:

  • 班級名稱
  • 祖先類名
  • 內容描述(和正規表示式)
  • 文字(和正規表示式)

iOS+ 支援上下文描述符中的以下觸發條件

  • 顯示正在測試的應用程式
  • 元素存在
  • 執行的非 Robo 腳本操作

結構

Robo 腳本有幾個屬性來描述 Robo 如何執行它。大多數這些屬性都是可選的,具有預先定義的預設值:

屬性描述
id一個整數,有助於在爬網輸出中追蹤此 Robo 腳本。 Robo 有內建的 Robo 腳本,有自己的id 。儘管不同 Robo 腳本中的相同id不會影響其行為,但在爬網輸出中區分這些 Robo 腳本的操作可能具有挑戰性。我們建議為您的 Robo 腳本分配1000或更高的唯一id ,以避免任何衝突。
descriptionid類似,但更具描述性。
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_presentelement_disabledelement_checked條件結合使用。與visionText互斥。有關詳細信息,請參閱元素描述符
visionText使用光學字元辨識 (OCR) API 偵測螢幕上的文字。 visionTextelement_present條件結合使用。與elementDescriptors互斥。
nonRoboscriptActionCount之前執行的連續非 Robo 腳本操作的數量。它與non_roboscript_action_performed條件結合使用,在每個nonRoboscriptActionCount Robo 操作後觸發 Robo 腳本。預設情況下,它是1

以下是由螢幕上顯示資源 ID "my.app.package:id/page_header"的 UI 小部件觸發的 Robo 腳本範例:

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

以下是由光學字元辨識 (OCR) 偵測到的"Privacy Policy"觸發的 Robo 腳本範例:

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

以下是 Robo 腳本的範例,該腳本在每個非腳本 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互斥。點按操作所需。

以下是 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 Java正規表示式來符合text
groupViewChildPositionrecyclerViewChildPositionadapterViewChildPosition表示 UI 小部件的子位置,取決於其父小部件的類型。

通常,這些屬性是未定義的,例如,按鈕可能沒有文字和內容描述。即使存在某些屬性值,它們在給定應用程式畫面上也可能不是唯一的(包括resourceId )。

例如,通常只能透過使用其父視窗小部件中的不同子位置來區分清單中的項目。這意味著僅使用一個元素描述符來標識 UI 小部件通常是不夠的。因此,操作的elementDescriptors屬性包含一系列元素描述符,這些元素描述符經過排序,第一個對應於目標 UI 小部件,第二個對應於目標 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"
      }
    ]
  }
]

執行選項

您可以選擇使用 JSON 物件為 Robo 腳本中的操作清單新增前綴,該物件指定該 Robo 腳本的執行選項。此配置標頭以roboscript關鍵字開頭,後面跟著所需執行選項的 JSON 表示形式。

Robo 腳本支援以下執行選項:

  • executionMode - Robo 腳本執行階段所應用的執行選項:
    • strict - 如果設定為true ,Robo 腳本不會採用部分匹配、跳過目前操作和中止。也就是說,Robo 腳本作為常規儀器測試執行,一旦無法執行任何操作就會失敗。預設情況下,它是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](#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_IGNOREDALL_ELEMENTS_IGNORED的「操作」。

每當包含忽略操作的 Robo 腳本的contextDescriptor屬性與給定螢幕匹配時,Robo 不會與其忽略操作所針對的任何UI 小部件交互(除非某些其他Robo 腳本操作使Robo 對被忽略的UI 小部件之一執行操作)。

Robo 腳本可以包含忽略、條件和非條件操作的混合。與其他 Robo 腳本操作不同,只要包含 Robo 腳本的contextDescriptor與 Robo 爬網期間的螢幕匹配,就會應用忽略操作,無論prioritymaxNumberOfRuns屬性的值如何。

以下是包含兩個 Robo 腳本的檔案範例。第一個 Robo 腳本讓 Robo 忽略螢幕上包含資源 ID 為"my.app.package:id/ignored_screen"的 UI 小部件的所有 UI 小部件。第二個 Robo 腳本讓 Robo 忽略資源 ID 與資源 ID 為"my.app.package:id/main_screen"的 UI 小部件的螢幕上的 Java 正規表示式".*:id/done" /done」匹配的UI 小部件:

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

RecyclerView 和 AdapterView 支持

RecyclerView 和 AdapterView 小工具的子級是動態載入的,並且可能會在遠離目前畫面的多次滑動中顯示。由於螢幕的大小以及到達該子項所需的滑動次數對於不同的裝置外形尺寸是不同的,因此依賴子項的資料位置(這是絕對的)要可靠得多。依賴將該子項目帶到螢幕然後使用其螢幕位置所需的滑動次數是一種不太穩健的方法。

因此,Robo 腳本捕獲作為 Robo 腳本操作目標的 RecyclerView 子級的絕對資料位置作為recyclerViewChildPosition 。 Robo 腳本也會擷取作為 Robo 腳本操作目標的 AdapterView 子層級的絕對資料位置作為adapterViewChildPosition

RecyclerView 和 AdapterView 子層級上的操作會依下列步驟執行:

  1. Robo 測試透過對其包含的 RecyclerView 或 AdapterView 進行定位操作,確保對應的子級顯示在螢幕上。

  2. Robo 測試會直接在子元素上執行記錄的操作,因為它已經顯示在螢幕上。

以下是 AdapterView ( android.widget.GridView ) 子層級上的點選操作的範例:

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

以下是 RecyclerView ( android.support.v7.widget.RecyclerView ) 子層級上的點選操作的範例:

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

在 Android Studio 中錄製 Robo 腳本並在測試實驗室中運行

您可以在 Android Studio 中建立 Robo 腳本,該腳本會將腳本儲存為 JSON 檔案。然後,您可以將 JSON 檔案與應用程式一起上傳到 Firebase 測試實驗室並相應地執行測試。

當您執行附加腳本的 Robo 測試時,Robo 測試會先執行預先編寫腳本的操作,然後像往常一樣探索應用程式。

若要在 Android Studio 中建立 Robo 腳本 JSON 文件,請按照使用 Android Studio 中的測試實驗室記錄 Robo 腳本中的步驟進行操作。

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指定當eventTypeSOFT_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 在螢幕上偵測到的"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 命令。

以下屬性是可選的:

  • 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 小部件執行五秒長的點擊:

{
  "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 操作

此操作會按下輸入法編輯器 (IME) 上指定目標 UI 小部件的目前操作按鈕,例如「下一步」、「完成」和「搜尋」。

下表列出了所需的屬性:

屬性描述
"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" --

以下是按 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 - DownRight ,取決於目標 UI 小部件的垂直或水平滾動性。
  • Backward - UpLeft ,取決於目標 UI 小部件的垂直或水平滾動性。
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 座標。與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"
    }
  ]
}

下一步