В этом документе представлена справочная информация о скриптах Robo, включая структуру, возможности, использование, запись и действия. Робо-скрипты — это тесты, которые автоматизируют задачи ручного обеспечения качества (QA) для мобильных приложений и обеспечивают стратегии непрерывной интеграции (CI) и тестирования перед запуском. Робо-скрипт — это файл JSON, описывающий последовательность пользовательского интерфейса (UI) и других действий.
Создать Robo-скрипт можно следующими способами:
Используйте функцию записи сценария Робо. (только для Android)
Создайте сценарий Робо вручную. (Android и iOS+)
Запишите сценарий Робо, а затем отредактируйте его вручную. (только для Android)
Дополнительные сведения об использовании сценариев 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
Robo для iOS+ (бета-версия) имеет ограниченную поддержку сценариев Robo. Синтаксис сценария Robo для iOS+ идентичен синтаксису Android, а поддерживаемые функции iOS+ ведут себя аналогично своим аналогам в Android.
В iOS+ поддерживаются следующие действия:
- Утверждение
- Нажмите
- Длинный щелчок
- Проведите пальцем по экрану
- Игнорировать все элементы
- Ждать
- Сделать скриншот
- Прекратить сканирование
Следующие идентифицирующие атрибуты в дескрипторах элементов поддерживаются в iOS+:
- Имя класса
- Имя класса-предка
- Описание контента (и регулярное выражение)
- Текст (и регулярное выражение)
В iOS+ поддерживаются следующие условия срабатывания в дескрипторах контекста :
- Показано тестируемое приложение
- Элемент присутствует
- Выполнено действие сценария, не относящегося к роботу
Структура
Скрипт Robo имеет несколько атрибутов, которые описывают, как Robo его выполняет. Большинство этих атрибутов являются необязательными и имеют предопределенные значения по умолчанию:
Атрибут | Описание |
id | Целое число, которое помогает отслеживать этот робот-скрипт в результатах сканирования. Robo имеет встроенные скрипты Robo со своими собственными id . Хотя один и тот же id в разных сценариях роботов не влияет на их поведение, отличить действия от этих сценариев роботов в результатах сканирования может быть непросто. Мы рекомендуем присваивать вашим сценариям Robo уникальный id 1000 или выше, чтобы избежать конфликтов. |
description | Похож на id , но более описателен. |
crawlStage | На этапе сканирования Робо применяет этот скрипт Робо. По умолчанию это основной этап сканирования. |
priority | Приоритет этого сценария Робо по сравнению с другими сценариями Робо. По умолчанию все сценарии Robo имеют приоритет 1 . |
maxNumberOfRuns | Указывает, сколько раз во время сканирования Robo может выполнить этот скрипт Robo. По умолчанию Robo может выполнить сценарий Robo один раз. |
contextDescriptor | Описывает контекст или условие, которое запускает этот скрипт Robo. Если этот параметр опущен, считается, что условие запуска этого Робо-скрипта всегда выполняется; другими словами, сценарий Робо является безусловным. |
actions | Все действия этого Робо скрипта. |
Один файл содержит набор из одного или нескольких сценариев 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 . |
"condition": "element_disabled" | Проверяет, что виджет пользовательского интерфейса, соответствующий elementDescriptors присутствует на экране и с ним невозможно взаимодействовать. |
"condition": "element_checked" | Проверяет, присутствует ли на экране виджет пользовательского интерфейса, соответствующий elementDescriptors , и проверяется. |
"condition": "app_under_test_shown" | Проверяет, что тестируемое приложение работает на переднем плане. |
"condition": "default_launcher_shown" | Проверяет, отображается ли главный экран устройства, что означает, что на переднем плане не работают никакие приложения. |
"condition": "non_roboscript_action_performed" | Проверяет, что последние последовательные действия nonRoboscriptActionCount , выполненные тестом Robo, не являются действиями сценария Robo. |
negateCondition | Если установлено значение true , condition отменяется. Например, вы можете использовать этот атрибут, чтобы проверить, НЕ присутствует ли виджет пользовательского интерфейса на экране или что тестируемое приложение НЕ работает на переднем плане. |
elementDescriptors | Один или несколько дескрипторов элементов, которые идентифицируют виджет пользовательского интерфейса на экране. Он используется в сочетании с условиями element_present , element_disabled и element_checked . Взаимоисключающее с visionText . Дополнительные сведения см. в разделе Дескрипторы элементов . |
visionText | Текст на экране обнаруживается с помощью API оптического распознавания символов (OCR). visionText используется в сочетании с условием element_present . Взаимоисключающий элемент с elementDescriptors . |
nonRoboscriptActionCount | Количество последовательных действий, не связанных с робо-скриптом, выполненных ранее. Он используется в сочетании с условием non_roboscript_action_performed для запуска сценария Robo после каждого действия робота, nonRoboscriptActionCount . По умолчанию это 1 . |
Ниже приведен пример сценария Robo, который запускается виджетом пользовательского интерфейса с идентификатором ресурса "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, который запускается "Privacy Policy"
обнаруженной с помощью оптического распознавания символов (OCR):
{
"id": 1000,
"description": "Vision text Robo script",
"contextDescriptor": {
"condition": "element_present",
"visionText": "Privacy Policy"
},
"actions": [
{
"eventType": "VIEW_CLICKED",
"visionText": "Privacy Policy"
}
]
}
Ниже приведен пример сценария робота, который ожидает 5 секунд после каждого действия робота, не связанного со сценарием:
{
"contextDescriptor": {
"condition": "non_roboscript_action_performed"
},
"maxNumberOfRuns" : 1000,
"actions" : [
{
"eventType" : "DELAYED_MESSAGE_POSTED",
"delayTime" : 5000
}]
}
Действия
Каждое действие в сценарии Robo представлено как набор из одной или нескольких пар атрибут-значение, которые описаны в следующей таблице:
Атрибут | Описание |
eventType | Указывает тип действия, например щелчок, редактирование текста и т. д. Требуется для каждого действия. |
elementDescriptors | Дескрипторы, идентифицирующие виджет пользовательского интерфейса. Требуется для всех действий, имеющих целевой виджет пользовательского интерфейса, например нажатия определенной кнопки. |
optional | Если установлено значение true , это действие пропускается, если его невозможно выполнить. Например, это действие пропускается, если не удается найти целевой виджет пользовательского интерфейса на экране, при этом не происходит сбой содержащегося в нем сценария Robo. По умолчанию значение false . |
replacementText | Текст для ввода в целевой виджет пользовательского интерфейса. Требуется для действий по редактированию текста. |
swipeDirection | Определяет направление пролистывания. Требуется для действий смахивания. |
delayTime | Указывает продолжительность ожидания в миллисекундах. Требуется для действий ожидания. |
pointTapXCoordinate и pointTapYCoordinate | Координаты пикселей X и Y точки касания. Взаимоисключающие функции pointTapXPercent и pointTapYPercent . Требуется для действий касания точки. |
pointTapXPercent и pointTapYPercent | Процентные координаты X и Y точки касания. Взаимоисключающие функции pointTapXCoordinate и pointTapYCoordinate . Требуется для действий касания точки. |
Ниже приведен пример сценария Robo с двумя действиями без целевых виджетов пользовательского интерфейса. Это означает, что эти действия не работают с конкретным виджетом пользовательского интерфейса:
[
{
"eventType": "DELAYED_MESSAGE_POSTED",
"delayTime": 3000
},
{
"eventType": "PRESSED_BACK"
}
]
Дескрипторы элементов
Дескриптор элемента идентифицирует виджет пользовательского интерфейса, используя один или несколько из следующих идентифицирующих атрибутов:
Атрибут | Описание |
className | – |
ancestorClassName | Имя класса предка иерархии пользовательского интерфейса элемента. Предком является любой из родительских узлов в иерархии пользовательского интерфейса элемента, включая сам элемент. |
resourceId | – |
resourceIdRegex | Регулярное выражение Java для соответствия resourceId . |
contentDescription | – |
contentDescriptionRegex | Регулярное выражение Java для соответствия contentDescription . |
text (который появляется на экране) | – |
textRegex | Регулярное выражение Java для сопоставления text . |
groupViewChildPosition , recyclerViewChildPosition или adapterViewChildPosition | Представляет дочернюю позицию виджета пользовательского интерфейса в зависимости от типа его родительского виджета. |
Часто эти атрибуты не определены, например, кнопка может не иметь текста и описания содержимого. Даже если присутствуют некоторые значения атрибутов, они могут не быть уникальными на данном экране приложения (включая resourceId
).
Например, различение элементов списка обычно возможно только путем использования их разных дочерних позиций в родительском виджете. Это означает, что использования всего лишь одного дескриптора элемента для идентификации виджета пользовательского интерфейса обычно недостаточно. Таким образом, атрибут elementDescriptors
действия содержит последовательность дескрипторов элементов, которые упорядочены таким образом, что первый соответствует целевому виджету пользовательского интерфейса, второй соответствует родительскому виджету целевого виджета пользовательского интерфейса и т. д. Целевой виджет пользовательского интерфейса действия соответствует, когда все его дескрипторы элементов соответствуют соответствующей подиерархии виджетов пользовательского интерфейса.
Ниже приведен пример сценария Robo с изменением текста и действиями по щелчку, оба из которых требуют, чтобы вы идентифицировали целевой виджет пользовательского интерфейса, используя предоставленные дескрипторы элементов:
[
{
"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-представление желаемых параметров выполнения.
Робо-скрипты поддерживают следующие варианты выполнения:
-
executionMode
— параметры выполнения, применяемые при запуске Robo-скрипта:-
strict
— если установлено значениеtrue
, скрипт Robo не использует частичное сопоставление, пропуск текущего действия и приостановку . То есть Робо-скрипт выполняется как обычный инструментальный тест и завершается сбоем, как только какое-либо из его действий невозможно выполнить. По умолчанию этоfalse
. -
dismiss_popups
— если установлено значениеtrue
, тест Robo закрывает любые неожиданные диалоговые окна при выполнении сценария Robo даже вstrict
режиме. Эта опция не имеет эффекта, если не находится вstrict
режиме. По умолчанию этоfalse
. -
notify
— если установлено значениеfalse
, скрипт Robo не отображает уведомления на экране в начале и конце своего выполнения. По умолчанию этоtrue
.
-
-
postscript
— параметры выполнения, применяемые после завершения сценария Robo:-
terminate
— если установлено значениеtrue
, робот-тест прекращает сканирование после завершения сценария Робо. По умолчанию этоfalse
.
-
Ниже приведен пример сценария Robo, выполняемого в strict
режиме без экранных уведомлений, который находится в режиме ожидания в течение трех секунд, после чего сканирование прекращается:
"roboscript": {
"executionMode": {
"strict": true,
"notify": false
},
"postscript": {
"terminate": true
}
}
[
{
"eventType": "DELAYED_MESSAGE_POSTED",
"delayTime": 3000
}
]
Параметры шаблона
Параметр шаблона — это заполнитель в сценарии Robo, который заменяется фактическим значением, когда тест Robo загружает этот сценарий Robo для выполнения. Параметры шаблона начинаются с двойного подчеркивания, за которым следует знак процента, и заканчиваются знаком процента, за которым следует двойное подчеркивание.
Робо-скрипты поддерживают следующий параметр шаблона:
-
__%APP_PACKAGE_NAME%__
— имя пакета тестируемого приложения.
Ниже приведен пример сценария Robo, который останавливает процесс тестируемого приложения:
[
{
"eventType": "ADB_SHELL_COMMAND",
"command": "am force-stop __%APP_PACKAGE_NAME%__"
}
]
Комментарии
Робо-скрипт может содержать строки комментариев, которые начинаются с #
или //
.
Ниже приведен пример сценария 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 не обязательно должны быть прологом к тесту Robo, и вы можете чередовать действия сценария Robo со стандартными действиями теста Robo. Этот метод поддерживает сценарии, когда поведение приложения нестабильно или когда изменения между версиями приложения достаточно велики, и тест Robo должен «заполнить пробелы» своими стандартными действиями. |
Приоритеты
Если сценарий Robo достигает своего maxNumberOfRuns
, его больше нельзя будет запустить при данном сканировании. Если в текущем контексте может быть запущено более одного сценария Робо, приоритет отдается путем выбора в следующем порядке сценария Робо, который:
- Имеет атрибут
contextDescriptor
. - Имеет наивысший
priority
(по умолчанию все скрипты Robo имеют одинаковыйpriority
выполнения —1
). - Появляется самым ранним в списке роботизированных сценариев, если приоритеты роботизированных сценариев совпадают.
Ниже приведен пример файла с тремя сценариями 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 script 3"
как последний применимый Робо-скрипт.
Повторные прогоны
По умолчанию Robo запускает сценарий Robo не чаще одного раза во время сканирования. Это можно настроить с помощью атрибута maxNumberOfRuns
.
Ниже приведен пример сценария Robo, который переводит тестируемое приложение в фоновый режим до 10 раз:
{
"id": 1000,
"maxNumberOfRuns": 10,
"contextDescriptor": {
"condition": "app_under_test_shown"
},
"actions": [
{
"eventType": "GO_HOME"
}
]
}
Этап сканирования
Робо-скрипты применимы на разных этапах конкретного роботизированного сканирования:
Этап сканирования | Описание |
pre_crawl | Прежде чем Robo запустит и начнет сканировать тестируемое приложение. |
post_crawl | После того, как Robo завершит сканирование тестируемого приложения. Робот-скрипт post_crawl не должен превышать 15 секунд, иначе сканирование может завершиться по истечении тайм-аута. |
crawl | Основной этап сканирования, на котором робот сканирует тестируемое приложение. |
close_screen | Когда Робо пытается вернуться назад (назад) с заданного экрана, когда исследованы все возможные действия на этом экране. По умолчанию Робо нажимает в ответ, что в некоторых сценариях нежелательно. |
Если атрибут crawlStage
скрипта Robo не указан, подразумевается, что это 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"
}
]
}
]
}
Условные действия
Робо-скрипт может содержать условные действия. У условных действий есть три дополнительных атрибута, которые описывают, как робот их выполняет:
Атрибут | Описание |
priority | Приоритет этого условного действия по сравнению с другими условными действиями в содержащем его скрипте Robo. По умолчанию все условные действия имеют приоритет 1 . |
maxNumberOfRuns | Сколько раз это условное действие может быть выполнено за одно выполнение содержащего его Robo-скрипта. По умолчанию все условные действия могут быть выполнены не более одного раза за одно выполнение содержащего их Robo-скрипта. |
contextDescriptor | Контекст/условие, которое запускает это условное действие. Он имеет ту же структуру и предлагает аналогичные возможности, что и contextDescriptor скрипта Robo. |
При срабатывании 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 игнорировать определенные виджеты пользовательского интерфейса или все виджеты пользовательского интерфейса на определенном экране. Эти инструкции представлены как игнорирующие «действия» с eventType
ELEMENT_IGNORED
и ALL_ELEMENTS_IGNORED
соответственно.
Всякий раз, когда атрибут contextDescriptor
сценария Robo, содержащего действия игнорирования, соответствует данному экрану, Robo не взаимодействует ни с какими виджетами пользовательского интерфейса, на которые направлены его действия игнорирования (если только какое-то другое действие сценария Robo не заставляет Robo выполнить действие над одним из игнорируемых виджетов пользовательского интерфейса).
Робо-скрипт может содержать смесь игнорирующих, условных и безусловных действий. В отличие от других действий сценария Robo, действия игнорирования применяются до тех пор, пока содержащий его contextDescriptor
сценария Robo соответствует экрану во время сканирования Robo, независимо от значений атрибутов priority
и maxNumberOfRuns
.
Ниже приведен пример файла с двумя сценариями Robo. Первый скрипт Robo заставляет Robo игнорировать все виджеты пользовательского интерфейса на экране, содержащем виджет пользовательского интерфейса с идентификатором ресурса "my.app.package:id/ignored_screen"
. Второй скрипт Robo заставляет Robo игнорировать виджеты пользовательского интерфейса, чьи идентификаторы ресурсов соответствуют регулярному выражению Java ".*:id/done"
на экране, содержащем виджет пользовательского интерфейса с идентификатором ресурса "my.app.package:id/main_screen"
:
[
{
"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 и AdaptorView загружаются динамически и могут отображаться при большом удалении от текущего экрана. Поскольку размер экрана и количество пролистываний, необходимых для доступа к этому дочернему элементу, различны для разных форм-факторов устройств, гораздо надежнее полагаться на положение данных дочернего элемента, которое является абсолютным. Менее надежный подход — полагаться на количество пролистываний, необходимых для того, чтобы вывести этого дочернего элемента на экран, а затем использовать его положение на экране.
Таким образом, сценарий Robo фиксирует абсолютные позиции данных дочерних элементов RecyclerView, которые являются целями действий сценария Robo, как recyclerViewChildPosition
. Сценарий Robo также фиксирует абсолютные позиции данных дочерних элементов AdaptorView, которые являются целями действий сценария Robo, как adapterViewChildPosition
.
Действия над дочерними элементами RecyclerView и AdaptorView выполняются в следующие шаги:
Робо-тест гарантирует, что соответствующий дочерний элемент отображается на экране посредством действия позиционирования на содержащем его RecyclerView или AdapterView.
Робо-тест выполняет записанное действие непосредственно над дочерним элементом, поскольку он уже отображается на экране.
Ниже приведен пример действия щелчка на дочернем элементе AdaptorView ( 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
}
]
}
Запишите сценарий Robo в Android Studio и запустите его в Test Lab
Вы можете создать сценарий Robo в Android Studio, который сохранит его в виде файла JSON. Затем вы можете загрузить файл JSON в Firebase Test Lab вместе с приложением и соответствующим образом запустить тест.
Когда вы запускаете роботизированный тест с прикрепленным сценарием, робототест сначала выполняет заранее заданные вами действия, а затем исследует приложение как обычно.
Чтобы создать JSON-файл сценария Robo в Android Studio, выполните действия, описанные в разделе Запись сценария Robo с помощью Test Lab в Android Studio .
Действия скрипта робота
Следующий общий необязательный атрибут применяется ко всем действиям:
-
description
— помогает отслеживать выполнение этого действия сценария робота в результатах теста робота.
Утверждение
Если заявленное условие истинно, сценарий Robo переходит к следующему действию, которое может быть другим утверждением. В противном случае выполнение сценария Robo будет остановлено из-за неудачного утверждения.
В следующей таблице перечислены обязательные атрибуты:
Атрибут | Описание |
"eventType": "ASSERTION" | -- |
contextDescriptor | Описывает заявленный контекст или условие. Он имеет ту же структуру и предлагает аналогичные возможности, что и contextDescriptor скрипта Robo . |
Ниже приведен пример утверждения сценария Robo, который проверяет, находится ли тестируемое приложение на переднем плане:
{
"eventType": "ASSERTION",
"contextDescriptor": {
"condition": "app_under_test_shown"
}
}
Ниже приведен пример утверждения сценария Робо, который проверяет наличие на экране виджета пользовательского интерфейса с идентификатором ресурса "com.google.samples.apps.topeka:id/done"
.
{
"eventType": "ASSERTION",
"contextDescriptor": {
"condition": "element_present",
"elementDescriptors": [
{
"resourceId": "com.google.samples.apps.topeka:id/done"
}
]
}
}
Ниже приведен пример утверждения сценария Робо, который проверяет, что "Settings"
НЕ обнаруживаются на экране с помощью OCR:
{
"eventType": "ASSERTION",
"contextDescriptor": {
"condition": "element_present",
"negateCondition": true,
"visionText": "Settings"
}
}
Нажмите
В следующей таблице перечислены обязательные атрибуты:
Атрибут | Описание |
---|---|
eventType | Указывает тип действия сценария Робо. |
"eventType": "VIEW_CLICKED" | Щелкает целевой элемент тестируемого приложения. |
"eventType": "SOFT_KEYBOARD_CLICK" | Щелкает целевой элемент программной клавиатуры. |
"eventType": "SOFT_KEYBOARD_RANDOM_CLICK" | Нажимает случайные элементы виртуальной клавиатуры до максимального числа раз maxNumberOfRuns . |
"eventType": "LIST_ITEM_CLICKED" | Используется программой записи сценариев Robo в Android Studio для щелчка по элементам списка. |
elementDescriptors | Идентифицирует выбранный виджет пользовательского интерфейса, используя иерархию пользовательского интерфейса Android. Взаимоисключающее с visionText . |
visionText | Идентифицирует выбранный элемент с помощью OCR. Взаимоисключающий элемент с elementDescriptors . |
matchIndex | Указывает индекс появления соответствующего целевого элемента, когда целевой элемент идентифицирован с помощью visionText . Если значение равно 0 , действие сценария Робо-скрипта выбирает первый совпадающий элемент, если оно равно 1 , действие сценария Робо-скрипта выбирает второй совпавший элемент и т. д. Порядок определяется слева направо, сверху вниз. Значение по умолчанию — 0 (выбирается первое совпадение). |
maxNumberOfRuns | Указывает, сколько раз следует щелкнуть случайный элемент виртуальной клавиатуры, если eventType имеет значение SOFT_KEYBOARD_RANDOM_CLICK . Значение по умолчанию — 1 . |
Ниже приведен пример действия сценария Робо, который нажимает кнопку с идентификатором ресурса "com.google.samples.apps.topeka:id/done"
:
{
"eventType": "VIEW_CLICKED",
"elementDescriptors": [
{
"resourceId": "com.google.samples.apps.topeka:id/done"
}
]
}
Ниже приведен пример действия сценария Робо, который щелкает второе вхождение слова "Search"
обнаруженного на экране с помощью OCR:
{
"eventType": "VIEW_CLICKED",
"visionText": "Search",
"matchIndex": 1
}
Ниже приведен пример действия сценария Робо, которое щелкает элемент программной клавиатуры с описанием содержимого "Emoji button"
:
{
"eventType": "SOFT_KEYBOARD_CLICK",
"elementDescriptors": [
{
"contentDescription": "Emoji button"
}
]
}
Ниже приведен пример действия сценария Робо, который щелкает случайные элементы программной клавиатуры до пяти раз:
{
"eventType": "SOFT_KEYBOARD_RANDOM_CLICK",
"maxNumberOfRuns": 5
}
Отключить программную клавиатуру
В следующей таблице перечислены обязательные атрибуты:
Атрибут | Описание |
"eventType": "DISABLE_KEYBOARD" | -- |
Ниже приведен пример действия сценария Робо, которое отключает виртуальную клавиатуру:
{
"eventType": "DISABLE_KEYBOARD"
}
Выполнить команду оболочки adb
В следующей таблице перечислены обязательные атрибуты:
Атрибут | Описание |
"eventType": "ADB_SHELL_COMMAND" | -- |
command | Команда оболочки Android Debug Bridge (adb), которую необходимо выполнить. |
Следующий атрибут является необязательным:
-
expectedOutputRegex
— ожидаемый вывод команды в виде регулярного выражения Java. Если выходные данные не совпадают, действие сценария Робо не будет выполнено. По умолчанию это пустая строка, что означает, что вывод не проверяется.
Ниже приведен пример действия сценария Робо, который очищает пользовательские данные тестируемого приложения:
{
"eventType": "ADB_SHELL_COMMAND",
"command": "pm clear __%APP_PACKAGE_NAME%__"
}
Предоставить разрешения
Это действие записывается устройством записи сценариев Robo в Android Studio для обеспечения обратной совместимости с Espresso Test Recorder . Робо-тест предоставляет все разрешения тестируемому приложению в начале каждого сканирования, поэтому это действие не выполняется. НЕ используйте это действие в своих скриптах Robo.
В следующей таблице перечислены обязательные атрибуты:
Атрибут | Описание |
"eventType": "PERMISSIONS_REQUEST" | -- |
Игнорировать все элементы на экране
Это действие заставляет Robo игнорировать все элементы на любом экране, который запускает содержащий его скрипт Robo.
В следующей таблице перечислены обязательные атрибуты:
Атрибут | Описание |
"eventType": "ALL_ELEMENTS_IGNORED" | -- |
Ниже приведен пример действия сценария Robo, которое заставляет Robo игнорировать все элементы на экране:
{
"eventType": "ALL_ELEMENTS_IGNORED"
}
Игнорировать элемент
Это действие заставляет Robo игнорировать элемент (или элементы), соответствующий указанным elementDescriptors
.
В следующей таблице перечислены обязательные атрибуты:
Атрибут | Описание |
"eventType": "ELEMENT_IGNORED" | -- |
elementDescriptors | Идентифицирует игнорируемые виджеты пользовательского интерфейса, используя иерархию пользовательского интерфейса Android. |
Следующий атрибут является необязательным:
-
ignoreChildren
— если установлено значениеtrue
, Robo также игнорирует всех потомков игнорируемых виджетов пользовательского интерфейса. По умолчанию этоfalse
.
Ниже приведен пример действия сценария Robo, которое заставляет Robo игнорировать все элементы, описания содержимого которых начинаются с "Avatar"
:
{
"eventType": "ELEMENT_IGNORED",
"elementDescriptors": [
{
"contentDescriptionRegex": "Avatar.*"
}
]
}
Введите текст
В следующей таблице перечислены обязательные атрибуты:
Атрибут | Описание |
---|---|
eventType | Указывает тип действия сценария Робо. |
"eventType": "VIEW_TEXT_CHANGED" | Вводит заданный текст в целевой виджет пользовательского интерфейса. |
"eventType": "ENTER_TEXT" | вводит заданный текст в целевой виджет пользовательского интерфейса, а затем отправляет событие KEYCODE_ENTER этому виджету пользовательского интерфейса. |
elementDescriptors | Идентифицирует целевой виджет пользовательского интерфейса, используя иерархию пользовательского интерфейса Android. |
replacementText | Текст для ввода в целевой виджет пользовательского интерфейса. |
Ниже приведен пример действия сценария Робо, которое вводит "John"
в виджет пользовательского интерфейса с идентификатором ресурса "com.google.samples.apps.topeka:id/first_name"
:
{
"eventType": "VIEW_TEXT_CHANGED",
"replacementText": "John",
"elementDescriptors": [
{
"resourceId": "com.google.samples.apps.topeka:id/first_name"
}
]
}
Длинный щелчок
В следующей таблице перечислены обязательные атрибуты:
Атрибут | Описание |
"eventType": "VIEW_LONG_CLICKED" | -- |
elementDescriptors | Идентифицирует целевой виджет пользовательского интерфейса, используя иерархию пользовательского интерфейса Android. Взаимоисключается с visionText . |
visionText | Идентифицирует элемент, на который щелкнули при длительном нажатии, с помощью OCR. Взаимоисключающий элемент с elementDescriptors . |
matchIndex | Указывает индекс появления соответствующего целевого элемента, когда целевой элемент идентифицирован с помощью visionText . Если он равен 0 , действие сценария робота выбирает первый совпавший элемент, если оно равно 1 , действие сценария робота выбирает второй совпавший элемент и т. д. Порядок определяется слева направо, сверху вниз. Значение по умолчанию — 0 (выбирается первое совпадение). |
Следующий атрибут является необязательным:
-
delayTime
— указывает, как долго длится нажатие длинного щелчка, в миллисекундах.
Ниже приведен пример действия сценария Робо, который выполняет пятисекундное нажатие на виджет пользовательского интерфейса с описанием содержимого "Avatar 8"
:
{
"eventType": "VIEW_LONG_CLICKED",
"elementDescriptors": [
{
"contentDescription": "Avatar 8"
}
],
"delayTime": 5000
}
Выполните одноточечный жест
В следующей таблице перечислены обязательные атрибуты:
Атрибут | Описание |
---|---|
"eventType": "ONE_POINT_GESTURE" | -- |
coordinates | Две координаты для одноточечного жеста в формате «(x1,y1)->(x2,y2)» в процентах или пикселях. |
Следующий атрибут является необязательным:
-
dragAndDrop
— если установлено значениеtrue
, одноточечный жест выполняет действие перетаскивания. По умолчанию этоfalse
.
Ниже приведен пример действия одноточечного жеста сценария Робо, выполняющего пролистывание вниз:
{
"eventType": "ONE_POINT_GESTURE",
"coordinates": "(50%,25%)->(50%,75%)"
}
Выполните двухточечный жест
В следующей таблице перечислены обязательные атрибуты:
Атрибут | Описание |
---|---|
"eventType": "TWO_POINT_GESTURE" | -- |
coordinates | Четыре координаты для двухточечного жеста в формате «(x1,y1)->(x2,y2),(x3,y3)->(x4,y4)» в процентах или пикселях. |
Ниже приведен пример действия сценария Робо, выполняющего жест разведения:
{
"eventType": "TWO_POINT_GESTURE",
"coordinates": "(50%,50%)->(25%,50%),(50%,50%)->(75%,50%)"
}
Выполнение действия IME
Это действие нажимает кнопку текущего действия, например «Далее», «Готово» и «Поиск», в редакторе метода ввода (IME) для указанного целевого виджета пользовательского интерфейса.
В следующей таблице перечислены обязательные атрибуты:
Атрибут | Описание |
---|---|
"eventType": "PRESSED_EDITOR_ACTION" | -- |
elementDescriptors | Идентифицирует целевой виджет пользовательского интерфейса, используя иерархию пользовательского интерфейса Android. |
Ниже приведен пример действия сценария Robo, которое выполняет действие IME над виджетом пользовательского интерфейса с идентификатором ресурса "com.google.samples.apps.topeka:id/first_name"
:
{
"eventType": "PRESSED_EDITOR_ACTION",
"elementDescriptors": [
{
"resourceId": "com.google.samples.apps.topeka:id/first_name"
}
]
}
Нажмите назад
В следующей таблице перечислены обязательные атрибуты:
Атрибут | Описание |
eventType | Указывает тип действия сценария Робо. |
"eventType": "PRESSED_BACK" | Отправляет на устройство событие KEYCODE_BACK . |
"eventType": "PRESSED_BACK_EMULATOR_28" | Используется устройством записи сценариев Robo в Android Studio для обратного вызова API 28 эмуляторов. |
Ниже приведен пример действия сценария Робо, которое нажимает назад:
{
"eventType": "PRESSED_BACK"
}
Нажмите домой
Это действие отправляет на устройство событие KEYCODE_HOME
.
В следующей таблице перечислены обязательные атрибуты:
Атрибут | Описание |
"eventType": "GO_HOME" | -- |
Ниже приведен пример действия сценария Робо, которое переходит в исходное положение:
{
"eventType": "GO_HOME"
}
Прокрутить элемент в поле зрения
Это действие заставляет тест Robo прокручивать виджет пользовательского интерфейса, соответствующий указанным elementDescriptors
, до тех пор, пока на экране не появится виджет пользовательского интерфейса, соответствующий указанным childElementDescriptors
, или пока прокручиваемый виджет больше не будет прокручиваться, или пока не будет достигнуто максимальное количество прокруток в 50.
В следующей таблице перечислены обязательные атрибуты:
Атрибут | Описание |
"eventType": "ELEMENT_SCROLL_INTO_VIEW" | -- |
elementDescriptors | Идентифицирует виджет пользовательского интерфейса с прокруткой, используя иерархию пользовательского интерфейса Android. |
childElementDescriptors | Идентифицирует виджет пользовательского интерфейса для прокрутки с использованием иерархии пользовательского интерфейса Android. |
Ниже приведен пример действия сценария Робо, которое прокручивает виджет пользовательского интерфейса с идентификатором ресурса "my.app.package:id/scrollable_card_container"
до тех пор, пока виджет пользовательского интерфейса с текстом "Orange"
не появится на экране (или больше не будет прокрутки). быть выполнено, или будет достигнуто максимальное количество прокруток в 50):
{
"eventType": "ELEMENT_SCROLL_INTO_VIEW",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/scrollable_card_container"
}
],
"childElementDescriptors": [
{
"text": "Orange"
}
]
}
Проведите пальцем по экрану
В следующей таблице перечислены обязательные атрибуты:
Атрибут | Описание |
---|---|
"eventType": "VIEW_SWIPED" | -- |
swipeDirection | Указывает направление смахивания:
|
elementDescriptors | Идентифицирует целевой виджет пользовательского интерфейса, используя иерархию пользовательского интерфейса Android. |
Ниже приведен пример действия сценария Робо, которое перемещает виджет пользовательского интерфейса с идентификатором ресурса "my.app.package:id/custom_content"
:
{
"eventType": "VIEW_SWIPED",
"swipeDirection": "Up",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/custom_content"
}
]
}
Сделать скриншот
В следующей таблице перечислены обязательные атрибуты:
Атрибут | Описание |
"eventType": "TAKE_SCREENSHOT" | -- |
screenshotName | Указывает имя файла снимка экрана. |
Ниже приведен пример действия сценария Робо, который делает снимок экрана:
{
"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 . |
Ниже приведен пример действия сценария Робо, которое касается середины экрана:
{
"eventType": "POINT_TAP",
"pointTapXPercent": 50,
"pointTapYPercent": 50
}
Коснитесь точки внутри элемента
В следующей таблице перечислены обязательные атрибуты:
Атрибут | Описание |
"eventType": "POINT_TAP_ELEMENT" | -- |
pointTapXPercent | Процентная координата X внутри целевого элемента. |
pointTapYPercent | Процентная координата Y внутри целевого элемента. |
elementDescriptors | Идентифицирует целевой виджет пользовательского интерфейса, используя иерархию пользовательского интерфейса Android. |
Ниже приведен пример действия сценария Робо, которое перемещает ползунок панели поиска вправо:
{
"eventType": "POINT_TAP_ELEMENT",
"pointTapXPercent": 80,
"pointTapYPercent": 50,
"elementDescriptors": [
{
"resourceId": "my.app.package:id/my_seekbar"
}
]
}
Прекратить сканирование
Это действие останавливает тест Робо.
В следующей таблице перечислены обязательные атрибуты:
Атрибут | Описание |
---|---|
"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. |
Ниже приведен пример действия сценария Робо, которое ожидает появления на экране виджета пользовательского интерфейса с идентификатором ресурса "my.app.package:id/confirmation_button"
в течение 30 секунд:
{
"eventType": "WAIT_FOR_ELEMENT",
"delayTime": 30000,
"elementDescriptors": [
{
"resourceId": "my.app.package:id/confirmation_button"
}
]
}