Robo 指令碼參考指南

本文件提供 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" 檢查畫面上是否有符合 elementDescriptorsvisionText 指定的文字的 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 偵測畫面上的文字。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 指定等待時間長度 (以毫秒為單位)。等待動作必填。
pointTapXCoordinatepointTapYCoordinate 觸碰點的像素 X 和 Y 座標。與 pointTapXPercentpointTapYPercent 互斥。點按動作時為必填。
pointTapXPercentpointTapYPercent 點選點的 X 和 Y 座標百分比。與 pointTapXCoordinatepointTapYCoordinate 互斥。點按動作時為必填。

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

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

元素描述元

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

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

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

舉例來說,您通常只能在父項小工具中使用不同的子項位置,才能區分清單項目。也就是說,只使用一個元素描述元來識別 UI 小工具通常是不夠的。因此,動作的 elementDescriptors 屬性包含一系列元素描述元經過排序的順序,讓第一個元素對應至目標 UI 小工具,第二個則對應至目標 UI 小工具的父項小工具,以此類推。只要動作的所有元素描述元都符合對應的 UI 小工具子階層,系統就會比對動作的目標 UI 小工具。

以下是含有文字變更和點擊動作的 Robo 指令碼範例,這兩項動作都需要使用提供的元素描述符來識別目標 UI 小工具:

[
  {
    "eventType": "VIEW_TEXT_CHANGED",
    "replacementText": "John",
    "elementDescriptors": [
      {
        "className": "android.support.v7.widget.AppCompatEditText",
        "groupViewChildPosition": 0,
        "resourceId": "com.google.samples.apps.topeka:id/first_name"
      },
      {
        "className": "android.widget.FrameLayout",
        "groupViewChildPosition": 0
      },
      {
        "className": "android.support.design.widget.TextInputLayout",
        "groupViewChildPosition": 1
      }
    ]
  },
  {
    "eventType": "VIEW_CLICKED",
    "elementDescriptors": [
      {
        "className": "android.support.design.widget.FloatingActionButton",
        "groupViewChildPosition": 1,
        "resourceId": "com.google.samples.apps.topeka:id/done"
      },
      {
        "className": "android.widget.FrameLayout",
        "groupViewChildPosition": 1,
        "resourceId": "com.google.samples.apps.topeka:id/content"
      },
      {
        "className": "android.widget.FrameLayout",
        "groupViewChildPosition": 0,
        "resourceId": "com.google.samples.apps.topeka:id/sign_in_content"
      }
    ]
  }
]

執行作業選項

您可以選擇在 Robo 指令碼中,為動作清單加上 JSON 物件前置字串,藉此指定該 Robo 指令碼的執行選項。此設定標頭以 roboscript 關鍵字開頭,後面接著所需執行選項的 JSON 表示法。

Robo 指令碼支援下列執行選項:

  • executionMode - 執行 Robo 指令碼時套用的執行選項:
    • strict - 如果設為 true,Robo 指令碼就不會採用部分比對、略過目前動作和暫停。也就是說,Robo 指令碼會以常規檢測測試的形式執行,並在無法執行任何動作時立即失敗。預設為 false
    • dismiss_popups - 如果設為 true,即使在 strict 模式下執行 Robo 指令碼,Robo 測試仍會關閉任何非預期的對話方塊。在非 strict 模式下,這個選項不會生效。預設為 false
    • notify:如果設為 false,Robo 指令碼不會在執行開始和結束時顯示畫面通知。預設為 true
  • postscript:在 Robo 指令碼完成後套用的執行選項:
    • terminate:如果設為 true,Robo 測試會在 Robo 指令碼完成後停止檢索。預設值為 false

以下是使用 strict 模式執行的 Robo 指令碼範例,其中沒有畫面上通知,且會休眠三秒,之後停止檢索:

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

範本參數

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

Robo 指令碼支援下列範本參數:

  • __%APP_PACKAGE_NAME%__:測試中的應用程式套件名稱。

以下是停止測試中應用程式程序的 Robo 指令碼範例:

[
  {
    "eventType": "ADB_SHELL_COMMAND",
    "command": "am force-stop __%APP_PACKAGE_NAME%__"
  }
]

留言

Robo 指令碼可包含註解行,也就是以 #// 開頭的行。

以下是含有幾個註解的 Robo 指令碼範例:

# Confirm a user account.
[
  {
    // Click the DONE button.
    "eventType": "VIEW_CLICKED",
    "elementDescriptors": [
      {
        "resourceId": "com.google.samples.apps.topeka:id/done"
      }
    ]
  }
]

功能

根據預設,Robo 指令碼的所有動作都完成 (或至少嘗試) 之前,Robo 指令碼都會持續運作。每當 Robo 測試要選取要執行的動作時,就會持續嘗試比對 Robo 指令碼動作。Robo 指令碼會採用下列技術來提高健全性:

技巧 說明
部分比對 如果目前的 Robo 指令碼動作無法完全比對,系統會放寬比對條件,並重試比對。部分比對不會考量最外層元素描述符,而是比對 Robo 指令碼動作的目標 UI 小工具。

如果部分比對成功,系統會照常執行對應的 Robo 指令碼動作。這項技術支援應用程式結構變更的情況,例如不同應用程式版本之間的畫面元素重新排列時。

略過目前的動作 如果目前的 Robo 指令碼動作無法完全或部分比對,Robo 會嘗試比對後續的 Robo 指令碼動作。如果後續動作完全或部分相符,Robo 測試會略過 (且從未返回) 目前的 Robo 指令碼動作,並執行後續動作。

此技巧可支援應用程式行為在不同版本之間變更或不穩定的情況,例如在錄製和重播 Robo 指令碼時,可能會在不同畫面上顯示間歇性對話方塊。

暫停 如果目前或後續的 Robo 指令碼動作無法完全或部分比對,Robo 指令碼會暫時停用,Robo 測試會使用其他策略挑選要執行的動作。這項動作完成後,Robo 測試會繼續執行 Robo 指令碼。

只要目前或後續的 Robo 指令碼動作無法比對,Robo 指令碼就會繼續暫停執行任何動作。因此,針對 Robo 測試,Robo 指令碼不一定需要冗長,而且您可以使用標準 Robo 測試動作來交錯 Robo 指令碼動作。這項技巧可支援應用程式行為不穩定,或應用程式版本之間的變更幅度太大,以致 Robo 測試需要使用標準動作「填補空白」的情況。

優先順序

如果 Robo 指令碼達到 maxNumberOfRuns,就無法再於特定檢索中觸發。如果目前的結構定義可以觸發多個 Robo 指令碼,系統會按照下列順序,為 Robo 指令碼選擇優先順序:

  1. 具有 contextDescriptor 屬性。
  2. 具有最高 priority (根據預設,所有 Robo 指令碼的執行 priority 都相同,為 1)。
  3. 如果 Robo 指令碼的優先順序相同,會最早出現在 Robo 指令碼清單中。

以下是檔案範例,其中包含三個執行相同動作的 Robo 指令碼,且由相同條件觸發 - 測試中的應用程式位於前景:

[
  {
    "id": 1000,
    "description": "Robo script 1",
    "contextDescriptor": {
      "condition": "app_under_test_shown"
    },
    "actions": [
      {
        "eventType": "DELAYED_MESSAGE_POSTED",
        "delayTime": 3000
      }
    ]
  },
  {
    "id": 1001,
    "description": "Robo script 2",
    "priority": "2",
    "contextDescriptor": {
      "condition": "app_under_test_shown"
    },
    "actions": [
      {
        "eventType": "DELAYED_MESSAGE_POSTED",
        "delayTime": 3000
      }
    ]
  },
  {
    "id": 1002,
    "description": "Robo script 3",
    "contextDescriptor": {
      "condition": "app_under_test_shown"
    },
    "actions": [
      {
        "eventType": "DELAYED_MESSAGE_POSTED",
        "delayTime": 3000
      }
    ]
  }
]

當測試中的應用程式處於前景時,Robo 會依序觸發下列動作:

  1. "Robo script 2",因為它具有最高優先順序。
  2. "Robo script 1",因為它在同優先順序的其他適用 Robo 指令碼中出現得較早。
  3. "Robo script 3" 為最後一個適用的 Robo 指令碼。

重複執行

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

以下是 Robo 指令碼範例,可將測試中的應用程式置於背景,最多 10 次:

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

檢索階段

Robo 指令碼可在特定 Robo 檢索的不同階段中使用:

檢索階段 說明
pre_crawl 在 Robo 啟動並開始檢索測試中的應用程式之前。
post_crawl Robo 完成檢索測試中的應用程式後,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_IGNOREDALL_ELEMENTS_IGNORED 的「actions」。

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

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

以下是含有兩個 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 子項的動作:

  1. Robo 測試可確保在包含 RecyclerView 或 AdapterView 的定位動作中,將對應的子項顯示在畫面上。

  2. 由於子項已顯示在畫面上,因此 Robo 測試會直接在子項上執行已記錄的動作。

以下是 AdapterView (android.widget.GridView) 子項上的點擊動作範例:

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

以下是 RecyclerView (android.support.v7.widget.RecyclerView) 子項的點擊動作範例:

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

在 Android Studio 中記錄 Robo 指令碼,並在 Test Lab 中執行

您可以在 Android Studio 中建立 Robo 指令碼,並將指令碼儲存為 JSON 檔案。接著,您可以透過應用程式將 JSON 檔案上傳至 Firebase Test Lab,並據此執行測試。

執行已附加指令碼的 Robo 測試時,Robo 會先執行預先編寫的動作進行測試,然後再照常探索應用程式。

如要在 Android Studio 中建立 Robo 指令碼 JSON 檔案,請按照「在 Android Studio 中使用 Test Lab 錄製 Robo 指令碼」一文的步驟操作。

Robo 指令碼動作

下列常見的選用屬性適用於所有動作:

  • description:協助在 Robo 測試輸出內容中追蹤這個 Robo 指令碼動作的執行作業。

斷言

如果斷言條件為 True,Robo 指令碼會繼續執行下一個動作,這可能是另一個斷言。否則,Robo 指令碼執行作業會因斷言失敗而停止。

下表列出必要的屬性:

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

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

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

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

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

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

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

點按

下表列出必要的屬性:

屬性 說明
eventType 指定 Robo 指令碼動作的類型。
"eventType": "VIEW_CLICKED" 按一下測試中應用程式的目標元素。
"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 指定 eventTypeSOFT_KEYBOARD_RANDOM_CLICK 時,要點按螢幕鍵盤隨機元素的次數。預設值為 1

以下是點按資源 ID "com.google.samples.apps.topeka:id/done" 的按鈕的 Robo 指令碼動作範例:

{
  "eventType": "VIEW_CLICKED",
  "elementDescriptors": [
    {
      "resourceId": "com.google.samples.apps.topeka:id/done"
    }
  ]
}

以下是 Robo 指令碼動作範例,會在使用 OCR 偵測到畫面上第二個 "Search" 字詞時點按該字詞:

{
  "eventType": "VIEW_CLICKED",
  "visionText": "Search",
  "matchIndex": 1
}

以下為點選包含內容說明 "Emoji button" 的 Robo 指令碼動作的 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 小工具上執行輸入法編輯器動作:

{
  "eventType": "PRESSED_EDITOR_ACTION",
  "elementDescriptors": [
    {
      "resourceId": "com.google.samples.apps.topeka:id/first_name"
    }
  ]
}

按下返回鍵

下表列出必要的屬性:

屬性 說明
eventType 指定 Robo 指令碼動作的類型。
"eventType": "PRESSED_BACK" KEYCODE_BACK 事件傳送至裝置。
"eventType": "PRESSED_BACK_EMULATOR_28" 由 Android Studio 中的 Robo 指令碼錄製器用於在模擬器 API 28 上按下返回鍵。

以下是按下返回鍵的 Robo 指令碼動作範例:

{
  "eventType": "PRESSED_BACK"
}

按下主畫面按鈕

這項動作會將 KEYCODE_HOME 事件傳送至裝置。

下表列出必要屬性:

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

以下是按下首頁的 Robo 指令碼動作範例:

{
  "eventType": "GO_HOME"
}

將元素捲動至檢視畫面

這個動作會讓 Robo 測試向前捲動符合指定 elementDescriptors 的 UI 小工具,直到畫面上出現符合指定 childElementDescriptors 的 UI 小工具,或捲動的小工具無法再捲動,或捲動次數達到 50 次上限為止。

下表列出必要屬性:

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

以下是 Robo 指令碼動作範例,該動作會捲動資源 ID "my.app.package:id/scrollable_card_container" 的 UI 小工具,直到畫面上出現文字為 "Orange" 的 UI 小工具為止 (或無法再執行捲動動作,或已達到 50 次捲動次數上限):

{
  "eventType": "ELEMENT_SCROLL_INTO_VIEW",
  "elementDescriptors": [
    {
      "resourceId": "my.app.package:id/scrollable_card_container"
    }
  ],
  "childElementDescriptors": [
    {
      "text": "Orange"
    }
  ]
}

滑動

下表列出必要的屬性:

屬性 說明
"eventType": "VIEW_SWIPED" --
swipeDirection 指定滑動方向:
  • Left
  • Right
  • Up
  • Down
  • Forward:視目標 UI 小工具的垂直或水平捲動功能而定,為 DownRight
  • Backward - UpLeft,視目標 UI 小工具的垂直或水平捲動性而定。
elementDescriptors 使用 Android UI 階層識別目標 UI 小工具。

以下是 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"
    }
  ]
}

後續步驟