В этом документе содержится справочная информация о скриптах Robo, включая структуру, возможности, использование, запись и действия. Скрипты Robo — это тесты, которые автоматизируют ручные задачи обеспечения качества (QA) для мобильных приложений и позволяют реализовать стратегии непрерывной интеграции (CI) и предварительного тестирования. Скрипт Robo — это файл JSON, описывающий последовательность пользовательского интерфейса (UI) и других действий.
Создать Robo-скрипт можно следующими способами:
Используйте функцию записи скрипта Robo. (Только для Android)
Создайте скрипт Robo вручную. (Android и iOS+)
Запишите скрипт Robo, а затем отредактируйте его вручную. (Только для 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+ (Beta) имеет ограниченную поддержку скриптов Robo. Синтаксис скрипта Robo для iOS+ идентичен синтаксису Android, а поддерживаемые функции iOS+ ведут себя аналогично своим аналогам Android.
В iOS+ поддерживаются следующие действия:
- Утверждение
- Нажмите
- Длительный щелчок
- Проведите пальцем
- Игнорировать все элементы
- Ждать
- Сделать снимок экрана
- Прекратить сканирование
В iOS+ поддерживаются следующие идентифицирующие атрибуты в дескрипторах элементов:
- Имя класса
- Имя класса-предка
- Описание контента (и регулярное выражение)
- Текст (и регулярное выражение)
В iOS+ поддерживаются следующие условия срабатывания в контекстных дескрипторах :
- Показано тестируемое приложение
- Элемент присутствует
- Выполнено действие не-роботизированного скрипта
Структура
Скрипт Robo имеет несколько атрибутов, которые описывают, как Robo его выполняет. Большинство этих атрибутов являются необязательными с предопределенными значениями по умолчанию:
Атрибут | Описание |
id | Целое число, которое помогает отслеживать этот скрипт Robo в результатах сканирования. Robo имеет встроенные скрипты Robo со своими собственными id . Хотя один и тот же id в разных скриптах Robo не влияет на их поведение, различение действий из этих скриптов Robo в результатах сканирования может быть сложной задачей. Мы рекомендуем назначать вашим скриптам Robo уникальный id 1000 или выше, чтобы избежать конфликтов. |
description | Похож на id , но более описательный. |
crawlStage | Этап сканирования Robo применяет этот скрипт Robo на. По умолчанию это основной этап сканирования. |
priority | Приоритет этого скрипта Robo по сравнению с другими скриптами Robo. По умолчанию все скрипты Robo имеют приоритет 1 . |
maxNumberOfRuns | Указывает, сколько раз во время сканирования Robo может выполнить этот скрипт Robo. По умолчанию Robo может выполнить скрипт Robo один раз. |
contextDescriptor | Описывает контекст или условие, которое запускает этот скрипт Robo. Если опущено, условие запуска этого скрипта Robo считается всегда выполненным; другими словами, скрипт Robo является безусловным. |
actions | Все действия этого скрипта Robo. |
Один файл содержит набор из одного или нескольких скриптов Robo.
Ниже приведен пример файла с двумя безусловными скриптами Robo, каждый из которых содержит одно действие, выполняемое один раз в начале сканирования:
[
{
"id": 1000,
"description": "My first Robo script",
"actions": [
{
"eventType": "DISABLE_KEYBOARD"
}
]
},
{
"id": 1001,
"description": "My second Robo script",
"actions": [
{
"eventType": "PRESSED_BACK"
}
]
}
]
Контекстный дескриптор
Контекстный дескриптор определяет контекст или условие, которое запускает скрипт Robo, используя один или комбинацию нескольких атрибутов:
Атрибут | Описание |
---|---|
"condition": "always" | Всегда запускает скрипт Robo. |
"condition": "element_present" | Проверяет, присутствует ли на экране виджет пользовательского интерфейса, соответствующий elementDescriptors или тексту, указанному visionText . |
"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 | Количество последовательных действий не-Robo-скрипта, выполненных ранее. Используется в сочетании с условием non_roboscript_action_performed для запуска Robo-скрипта после каждых nonRoboscriptActionCount действий Robo. По умолчанию это 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"
}
]
}
Ниже приведен пример скрипта Robo, который ждет 5 секунд после каждого действия Robo, не являющегося скриптом:
{
"contextDescriptor": {
"condition": "non_roboscript_action_performed"
},
"maxNumberOfRuns" : 1000,
"actions" : [
{
"eventType" : "WAIT",
"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": "WAIT",
"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 желаемых параметров выполнения.
Скрипты Robo поддерживают следующие варианты выполнения:
-
executionMode
— параметры выполнения, применяемые при запуске скрипта Robo:-
strict
- если установлено значениеtrue
, скрипт Robo не использует частичное соответствие, пропуск текущего действия и приостановку . То есть скрипт Robo выполняется как обычный инструментальный тест и завершается неудачей, как только любое из его действий не может быть выполнено. По умолчанию установлено значениеfalse
. -
dismiss_popups
— если установлено значениеtrue
, Robo test отклоняет любые неожиданные диалоги при выполнении скрипта Robo даже вstrict
режиме. Эта опция не действует, если режим неstrict
. По умолчанию она равнаfalse
. -
notify
- если установлено значениеfalse
, скрипт Robo не показывает уведомления на экране в начале и конце своего выполнения. По умолчанию установленоtrue
.
-
-
postscript
- параметры выполнения, применяемые после завершения скрипта Robo:-
terminate
- если установлено значениеtrue
, Robo test останавливает сканирование после завершения скрипта Robo. По умолчанию установлено значениеfalse
.
-
Ниже приведен пример скрипта Robo, выполняемого в strict
режиме без экранных уведомлений, который ждет три секунды, после чего сканирование останавливается:
"roboscript": {
"executionMode": {
"strict": true,
"notify": false
},
"postscript": {
"terminate": true
}
}
[
{
"eventType": "WAIT",
"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. Если частичное соответствие успешно, соответствующее действие скрипта Robo выполняется как обычно. Эта техника поддерживает сценарии, в которых структура приложения меняется, например, между версиями приложения, когда элементы экрана перестраиваются. |
Пропустить текущее действие | Если текущее действие скрипта Robo не может быть полностью или частично сопоставлено, Robo пытается сопоставить последующее действие скрипта Robo. Если последующее действие полностью или частично совпадает, тест Robo пропускает (и никогда не возвращается) текущее действие скрипта Robo и выполняет последующее. Этот метод поддерживает сценарии, когда поведение приложения меняется между версиями или работает нестабильно, например, когда прерывистый диалог может появляться на разных экранах во время записи или воспроизведения скрипта Robo. |
Приостановить | Если ни текущее, ни последующие действия скрипта Robo не могут быть полностью или частично сопоставлены, скрипт Robo временно приостанавливается, и тест Robo выбирает действие для выполнения, используя другие стратегии. После завершения этого действия тест Robo возобновляет выполнение скрипта Robo. Пока текущие или последующие действия скрипта Robo не могут быть сопоставлены, скрипт Robo остается приостановленным для любого количества действий. Таким образом, скрипты Robo не обязательно должны быть прологом для теста Robo, и вы можете перемежать действия скрипта Robo со стандартными действиями теста Robo. Этот метод поддерживает сценарии, когда поведение приложения нестабильно или когда изменения между версиями приложения достаточно велики, чтобы тест Robo должен был «заполнить пробелы» своими стандартными действиями. |
Приоритеты
Если скрипт Robo достигает своего maxNumberOfRuns
, он больше не может быть запущен в данном цикле. Если текущий контекст может запустить более одного скрипта Robo, приоритет отдается путем выбора в следующем порядке скрипта Robo, который:
- Имеет атрибут
contextDescriptor
. - Имеет наивысший
priority
(по умолчанию все скрипты Robo имеют одинаковыйpriority
выполнения1
). - Появляется первым в списке скриптов Robo, если приоритеты скриптов Robo одинаковы.
Ниже приведен пример файла с тремя скриптами Robo, которые выполняют одно и то же действие и запускаются при одном и том же условии — тестируемое приложение находится на переднем плане:
[
{
"id": 1000,
"description": "Robo script 1",
"contextDescriptor": {
"condition": "app_under_test_shown"
},
"actions": [
{
"eventType": "WAIT",
"delayTime": 3000
}
]
},
{
"id": 1001,
"description": "Robo script 2",
"priority": "2",
"contextDescriptor": {
"condition": "app_under_test_shown"
},
"actions": [
{
"eventType": "WAIT",
"delayTime": 3000
}
]
},
{
"id": 1002,
"description": "Robo script 3",
"contextDescriptor": {
"condition": "app_under_test_shown"
},
"actions": [
{
"eventType": "WAIT",
"delayTime": 3000
}
]
}
]
Когда тестируемое приложение находится на переднем плане, Robo запускает следующие действия в следующем порядке:
-
"Robo script 2"
, поскольку он имеет наивысший приоритет. -
"Robo script 1"
поскольку он появляется раньше среди оставшихся применимых Robo-скриптов с тем же приоритетом. -
"Robo script 3"
— последний применимый Robo script.
Повторные прогоны
По умолчанию Robo запускает скрипт Robo не чаще одного раза во время сканирования. Это можно настроить с помощью атрибута maxNumberOfRuns
.
Ниже приведен пример скрипта Robo, который переводит тестируемое приложение в фоновый режим до 10 раз:
{
"id": 1000,
"maxNumberOfRuns": 10,
"contextDescriptor": {
"condition": "app_under_test_shown"
},
"actions": [
{
"eventType": "GO_HOME"
}
]
}
Стадия ползания
Скрипты Robo применяются на разных этапах конкретного роботизированного сканирования:
Стадия ползания | Описание |
pre_crawl | Прежде чем Robo запустится и начнет сканирование тестируемого приложения. |
post_crawl | После того, как Robo закончит сканирование тестируемого приложения. Скрипт post_crawl Robo не должен длиться более 15 секунд, иначе сканирование может завершиться из-за тайм-аута. |
crawl | Основной этап сканирования, когда Robo сканирует тестируемое приложение. |
close_screen | Когда Robo пытается вернуться назад (backtrack) с заданного экрана, когда все возможные действия на этом экране исследованы. По умолчанию Robo нажимает назад, что нежелательно в некоторых сценариях. |
Если атрибут 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"
}
]
}
]
}
Условные действия
Скрипт Robo может содержать условные действия. Условные действия имеют три дополнительных атрибута, которые описывают, как Robo их выполняет:
Атрибут | Описание |
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": "WAIT",
"delayTime": 10000
},
{
"description": "Screen on",
"eventType": "ADB_SHELL_COMMAND",
"command": "input keyevent 82"
},
{
"description": "Wait for 10 seconds",
"eventType": "WAIT",
"delayTime": 10000
}
}
Игнорирование действий
Скрипт Robo может содержать инструкции для Robo игнорировать определенные виджеты пользовательского интерфейса или все виджеты пользовательского интерфейса на определенном экране. Эти инструкции представлены как игнорирование "действий" с eventType
ELEMENT_IGNORED
и ALL_ELEMENTS_IGNORED
соответственно.
Всякий раз, когда атрибут contextDescriptor
скрипта Robo, содержащего игнорируемые действия, соответствует заданному экрану, 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 и AdapterView загружаются динамически и могут отображаться на расстоянии многих смахиваний от текущего экрана. Поскольку размер экрана и количество смахиваний, необходимых для перехода к дочернему элементу, различаются для разных форм-факторов устройств, гораздо надежнее полагаться на позицию данных дочернего элемента, которая является абсолютной. Менее надежный подход — полагаться на количество смахиваний, необходимых для вывода дочернего элемента на экран, а затем использовать его позицию на экране.
Таким образом, скрипт Robo захватывает абсолютные позиции данных дочерних элементов RecyclerView, которые являются целями действий скрипта Robo, как recyclerViewChildPosition
. Скрипт Robo также захватывает абсолютные позиции данных дочерних элементов AdapterView, которые являются целями действий скрипта Robo, как adapterViewChildPosition
.
Действия над дочерними элементами RecyclerView и AdapterView выполняются в следующей последовательности:
Тест Robo обеспечивает отображение соответствующего дочернего элемента на экране посредством действия позиционирования на содержащем его RecyclerView или AdapterView.
Robo-тест выполняет записанное действие непосредственно над дочерним элементом, поскольку оно уже отображается на экране.
Ниже приведен пример действия щелчка на дочернем элементе AdapterView ( android.widget.GridView
):
{
"eventType": "VIEW_CLICKED",
"elementDescriptors": [
{
"className": "com.google.samples.apps.topeka.widget.AvatarView",
"adapterViewChildPosition": 5,
"resourceId": "com.google.samples.apps.topeka:id/avatar",
"contentDescription": "Avatar 6"
},
{
"className": "android.widget.GridView",
"groupViewChildPosition": 1,
"resourceId": "com.google.samples.apps.topeka:id/avatars"
},
{
"className": "android.widget.LinearLayout",
"groupViewChildPosition": 1
},
{
"className": "android.widget.LinearLayout",
"groupViewChildPosition": 0
}
]
}
Ниже приведен пример действия щелчка на дочернем элементе RecyclerView ( android.support.v7.widget.RecyclerView
):
{
"eventType": "VIEW_CLICKED",
"elementDescriptors": [
{
"className": "android.support.v7.widget.AppCompatTextView",
"groupViewChildPosition": 1,
"resourceId": "com.google.samples.apps.topeka:id/category_title"
},
{
"className": "android.widget.FrameLayout",
"recyclerViewChildPosition": 8,
"resourceId": "com.google.samples.apps.topeka:id/category_item"
},
{
"className": "android.support.v7.widget.RecyclerView",
"groupViewChildPosition": 1,
"resourceId": "com.google.samples.apps.topeka:id/categories"
},
{
"className": "android.widget.FrameLayout",
"groupViewChildPosition": 1,
"resourceId": "com.google.samples.apps.topeka:id/category_container"
},
{
"className": "android.widget.LinearLayout",
"groupViewChildPosition": 0
}
]
}
Запишите скрипт Robo в Android Studio и запустите его в Test Lab
Вы можете создать скрипт Robo в Android Studio, который сохранит скрипт как файл JSON. Затем вы можете загрузить файл JSON в Firebase Test Lab вместе с приложением и запустить тест соответствующим образом.
При запуске Robo-теста с прикрепленным сценарием Robo-тест сначала выполняет заранее заданные действия, а затем исследует приложение как обычно.
Чтобы создать JSON-файл скрипта Robo в Android Studio, следуйте инструкциям в разделе Запись скрипта Robo с помощью Test Lab в Android Studio .
Действия скрипта Robo
Следующий общий необязательный атрибут применяется ко всем действиям:
-
description
- помогает отслеживать выполнение этого действия скрипта Robo в выходных данных теста Robo.
Утверждение
Если утверждаемое условие истинно, скрипт Robo переходит к следующему действию, которое может быть другим утверждением. В противном случае выполнение скрипта Robo останавливается из-за невыполненного утверждения.
В следующей таблице перечислены требуемые атрибуты:
Атрибут | Описание |
"eventType": "ASSERTION" | -- |
contextDescriptor | Описывает утверждаемый контекст или условие. Имеет ту же структуру и предлагает аналогичные возможности, что и contextDescriptor скрипта Robo . |
Ниже приведен пример утверждения скрипта Robo, который проверяет, находится ли тестируемое приложение на переднем плане:
{
"eventType": "ASSERTION",
"contextDescriptor": {
"condition": "app_under_test_shown"
}
}
Ниже приведен пример утверждения скрипта Robo, который проверяет наличие на экране виджета пользовательского интерфейса с идентификатором ресурса "com.google.samples.apps.topeka:id/done"
:
{
"eventType": "ASSERTION",
"contextDescriptor": {
"condition": "element_present",
"elementDescriptors": [
{
"resourceId": "com.google.samples.apps.topeka:id/done"
}
]
}
}
Ниже приведен пример утверждения скрипта Robo, который проверяет, что "Settings"
НЕ обнаружены на экране с помощью OCR:
{
"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" | Используется средством записи скриптов Robo в Android Studio для нажатия на элементы списка. |
elementDescriptors | Определяет выбранный виджет пользовательского интерфейса с помощью иерархии пользовательского интерфейса Android. Взаимоисключающее с visionText . |
visionText | Идентифицирует выбранный элемент с помощью OCR. Взаимоисключающее с elementDescriptors . |
matchIndex | Указывает индекс вхождения совпавшего целевого элемента, когда целевой элемент идентифицируется с помощью visionText . Если он равен 0 , действие скрипта Robo выбирает первый совпавший элемент, если он равен 1 , действие скрипта Robo выбирает второй совпавший элемент и т. д. Порядок определяется слева направо, сверху вниз. Значение по умолчанию равно 0 (выбирается первое совпадение). |
maxNumberOfRuns | Указывает, сколько раз следует щелкнуть случайный элемент программной клавиатуры, когда eventType — SOFT_KEYBOARD_RANDOM_CLICK . Значение по умолчанию — 1 . |
Ниже приведен пример действия скрипта Robo, который нажимает кнопку с идентификатором ресурса "com.google.samples.apps.topeka:id/done"
:
{
"eventType": "VIEW_CLICKED",
"elementDescriptors": [
{
"resourceId": "com.google.samples.apps.topeka:id/done"
}
]
}
Ниже приведен пример действия скрипта Robo, который нажимает на второе вхождение слова "Search"
обнаруженное на экране с помощью OCR:
{
"eventType": "VIEW_CLICKED",
"visionText": "Search",
"matchIndex": 1
}
Ниже приведен пример действия скрипта 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
В следующей таблице перечислены требуемые атрибуты:
Атрибут | Описание |
"eventType": "ADB_SHELL_COMMAND" | -- |
command | Команда оболочки Android Debug Bridge (adb), которую необходимо выполнить. |
Следующий атрибут является необязательным:
-
expectedOutputRegex
— ожидаемый вывод команды в виде регулярного выражения Java. Если вывод не совпадает, действие скрипта Robo завершается неудачей. По умолчанию это пустая строка, что означает, что вывод не проверяется.
Ниже приведен пример действия скрипта Robo, который очищает данные пользователя тестируемого приложения:
{
"eventType": "ADB_SHELL_COMMAND",
"command": "pm clear __%APP_PACKAGE_NAME%__"
}
Предоставить разрешения
Это действие записывается Robo script recorder в Android Studio для обратной совместимости с Espresso Test Recorder . Robo test предоставляет все разрешения тестируемому приложению в начале каждого сканирования, и, таким образом, это действие является пустым. НЕ используйте это действие в своих Robo scripts.
В следующей таблице перечислены требуемые атрибуты:
Атрибут | Описание |
"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 | Указывает тип действия скрипта Robo. |
"eventType": "VIEW_TEXT_CHANGED" | Вводит указанный текст в целевой виджет пользовательского интерфейса. |
"eventType": "ENTER_TEXT" | вводит заданный текст в целевой виджет пользовательского интерфейса, а затем отправляет событие KEYCODE_ENTER этому виджету пользовательского интерфейса. |
elementDescriptors | Определяет целевой виджет пользовательского интерфейса с помощью иерархии пользовательского интерфейса Android. |
replacementText | Текст для ввода в целевой виджет пользовательского интерфейса. |
Ниже приведен пример действия скрипта Robo, который вводит "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 , действие скрипта Robo выбирает первый совпавший элемент, если он равен 1 , действие скрипта Robo выбирает второй совпавший элемент и т. д. Порядок определяется слева направо, сверху вниз. Значение по умолчанию равно 0 (выбирается первое совпадение). |
Следующий атрибут является необязательным:
-
delayTime
— указывает, как долго длится нажатие при длинном щелчке, в миллисекундах.
Ниже приведен пример действия скрипта Robo, который выполняет пятисекундный щелчок по виджету пользовательского интерфейса с описанием содержимого "Avatar 8"
:
{
"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) для указанного целевого виджета пользовательского интерфейса.
В следующей таблице перечислены требуемые атрибуты:
Атрибут | Описание |
---|---|
"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 | Указывает тип действия скрипта Robo. |
"eventType": "PRESSED_BACK" | Отправляет на устройство событие KEYCODE_BACK . |
"eventType": "PRESSED_BACK_EMULATOR_28" | Используется средством записи скриптов Robo в Android Studio для обратного нажатия на эмуляторы API 28. |
Ниже приведен пример действия скрипта Robo, который нажимает «назад»:
{
"eventType": "PRESSED_BACK"
}
Пресс-центр
Это действие отправляет на устройство событие KEYCODE_HOME
.
В следующей таблице перечислены требуемые атрибуты:
Атрибут | Описание |
"eventType": "GO_HOME" | -- |
Ниже приведен пример действия скрипта Robo, которое приводит к щелчку:
{
"eventType": "GO_HOME"
}
Прокрутите элемент в поле зрения
Это действие заставляет Robo test прокручивать вперед виджет пользовательского интерфейса, соответствующий указанным elementDescriptors
, до тех пор, пока на экране не появится виджет пользовательского интерфейса, соответствующий указанным childElementDescriptors
, или пока прокручиваемый виджет больше не сможет прокручиваться, или пока не будет достигнуто максимальное количество прокруток в 50.
В следующей таблице перечислены требуемые атрибуты:
Атрибут | Описание |
"eventType": "ELEMENT_SCROLL_INTO_VIEW" | -- |
elementDescriptors | Определяет прокручиваемый виджет пользовательского интерфейса с помощью иерархии пользовательского интерфейса Android. |
childElementDescriptors | Определяет виджет пользовательского интерфейса для прокрутки с использованием иерархии пользовательского интерфейса Android. |
Ниже приведен пример действия скрипта Robo, который прокручивает виджет пользовательского интерфейса с идентификатором ресурса "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. |
Ниже приведен пример действия скрипта Robo, который смахивает виджет пользовательского интерфейса с идентификатором ресурса "my.app.package:id/custom_content"
:
{
"eventType": "VIEW_SWIPED",
"swipeDirection": "Up",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/custom_content"
}
]
}
Сделать снимок экрана
В следующей таблице перечислены требуемые атрибуты:
Атрибут | Описание |
"eventType": "TAKE_SCREENSHOT" | -- |
screenshotName | Указывает имя файла снимка экрана. |
Ниже приведен пример действия скрипта Robo, который делает снимок экрана:
{
"eventType": "TAKE_SCREENSHOT",
"screenshotName": "my_screenshot"
}
Нажмите на точку на экране
В следующей таблице перечислены требуемые атрибуты:
Атрибут | Описание |
---|---|
"eventType": "POINT_TAP" | -- |
pointTapXCoordinate | Координата X пикселя точки нажатия. Взаимоисключающее с pointTapXPercent и pointTapYPercent . |
pointTapYCoordinate | Координата Y пикселя точки нажатия. Взаимоисключающее с pointTapXPercent и pointTapYPercent . |
pointTapXPercent | Процентная координата X точки касания. Взаимоисключающая с pointTapXCoordinate и pointTapYCoordinate . |
pointTapYPercent | Процентная координата Y точки касания. Взаимоисключающая с pointTapXCoordinate и pointTapYCoordinate . |
Ниже приведен пример действия скрипта Robo, который нажимает на середину экрана:
{
"eventType": "POINT_TAP",
"pointTapXPercent": 50,
"pointTapYPercent": 50
}
Нажмите на точку внутри элемента
В следующей таблице перечислены требуемые атрибуты:
Атрибут | Описание |
"eventType": "POINT_TAP_ELEMENT" | -- |
pointTapXPercent | Процентная координата X внутри целевого элемента. |
pointTapYPercent | Процентная координата Y внутри целевого элемента. |
elementDescriptors | Определяет целевой виджет пользовательского интерфейса с использованием иерархии пользовательского интерфейса Android. |
Ниже приведен пример действия скрипта 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": "WAIT" (or "DELAYED_MESSAGE_POSTED") | -- |
delayTime | Указывает время ожидания в миллисекундах. |
Ниже приведен пример действия скрипта Robo, который ждет три секунды:
{
"eventType": "WAIT",
"delayTime": 3000
}
Подождите элемент
Это действие заставляет Robo test ждать появления элемента на экране в течение указанного времени ожидания.
В следующей таблице перечислены требуемые атрибуты:
Атрибут | Описание |
"eventType": "WAIT_FOR_ELEMENT" | -- |
delayTime | Указывает время ожидания в миллисекундах. |
elementDescriptors | Идентифицирует ожидаемый виджет пользовательского интерфейса с помощью иерархии пользовательского интерфейса Android. |
Ниже приведен пример действия скрипта Robo, который ожидает до 30 секунд, пока на экране появится виджет пользовательского интерфейса с идентификатором ресурса "my.app.package:id/confirmation_button"
:
{
"eventType": "WAIT_FOR_ELEMENT",
"delayTime": 30000,
"elementDescriptors": [
{
"resourceId": "my.app.package:id/confirmation_button"
}
]
}