В этом документе приведена справочная информация о скриптах Robo, в том числе об их структуре, возможностях, использовании, записи и действиях. Скрипты Robo – это тесты, которые автоматизируют задачи по обеспечению качества мобильных приложений и позволяют реализовать стратегии непрерывной интеграции и тестирования перед запуском. Roboscript – это файл JSON, в котором описана последовательность действий в пользовательском интерфейсе и других действий.
Создать скрипт Robo можно следующими способами:
Использовать функцию записи скрипта автоматизированного тестирования. (только для Android)
Создайте скрипт Robo вручную. (Android и iOS+)
Запишите скрипт Robo, а затем отредактируйте его вручную. (только для Android)
Подробнее о том, как запустить скрипт Robo…
Введение
Скрипт Robo предоставляется для автоматизированного тестирования вместе с другими входными данными, такими как пакет приложения Android (APK) тестируемого приложения.
Ниже приведен пример скрипта Robo, который позволяет войти в приложение при его запуске:
[
{
"crawlStage": "crawl",
"contextDescriptor": {
"condition": "app_under_test_shown"
},
"actions": [
{
"eventType": "VIEW_TEXT_CHANGED",
"replacementText": "user123",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/username"
}
]
},
{
"eventType": "VIEW_TEXT_CHANGED",
"replacementText": "12345",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/password"
}
]
},
{
"eventType": "VIEW_CLICKED",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/login"
}
]
}
]
}
]
Если в файле только один скрипт Robo и у него условие запуска по умолчанию app_under_test_shown, как в примере выше, то скрипт Robo в файле можно указать в более простом формате – просто как последовательность действий:
[
{
"eventType": "VIEW_TEXT_CHANGED",
"replacementText": "user123",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/username"
}
]
},
{
"eventType": "VIEW_TEXT_CHANGED",
"replacementText": "12345",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/password"
}
]
},
{
"eventType": "VIEW_CLICKED",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/login"
}
]
}
]
Поддержка скриптов Robo в iOS+
Robo для iOS+ (бета-версия) ограниченно поддерживает скрипты Robo. Синтаксис скриптов Robo для iOS+ идентичен синтаксису для Android, а поддерживаемые функции iOS+ работают так же, как и аналогичные функции Android.
В iOS+ поддерживаются следующие действия:
- Утверждение
- Клик
- Нажать и удерживать
- Пролистните
- Игнорировать все элементы
- Пауза
- Сделать скриншот
- Остановить сканирование
В iOS+ поддерживаются следующие атрибуты идентификации в дескрипторах элементов:
- Название курса
- Название класса предка
- Описание контента (и регулярное выражение)
- Текст (и регулярное выражение)
В iOS+ поддерживаются следующие условия активации в дескрипторах контекста:
- Показано тестируемое приложение
- Элемент присутствует
- Выполнено действие, не связанное с Robo-скриптом
Структура
У скрипта Robo есть несколько атрибутов, которые описывают, как он выполняется. Большинство этих атрибутов необязательны и имеют заданные по умолчанию значения:
| Атрибут | Описание |
id
|
Целое число, которое помогает отслеживать этот скрипт Robo в результатах сканирования.
У Robo есть встроенные скрипты Robo со своими id. Хотя одинаковые id в разных скриптах Robo не влияют на их поведение, различать действия из этих скриптов в результатах сканирования может быть сложно. Чтобы избежать конфликтов, рекомендуем присвоить скриптам Robo уникальный id со значением 1000 или выше.
|
description
|
Аналогично id, но более описательно.
|
crawlStage
|
Этап сканирования, на котором Robo применяет этот скрипт. По умолчанию это основной этап сканирования. |
priority
|
Приоритет этого скрипта Robo по сравнению с другими скриптами Robo.
По умолчанию все скрипты Robo имеют приоритет 1.
|
maxNumberOfRuns
|
Указывает, сколько раз во время сканирования робот может выполнить этот скрипт. По умолчанию робот может выполнить скрипт автоматизированного тестирования только один раз. |
contextDescriptor
|
Описывает контекст или условие, которое запускает этот скрипт 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 последовательных действий, выполненных при автоматизированном тестировании, не являются действиями скрипта автоматизированного тестирования.
|
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"
}
]
}
Ниже приведен пример скрипта Robo, который ждет пять секунд после каждого действия 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, в котором будут указаны параметры выполнения этого скрипта. Заголовок конфигурации начинается с ключевого слова roboscript, за которым следует представление нужных параметров выполнения в формате JSON.
Скрипты Robo поддерживают следующие варианты выполнения:
executionMode– параметры выполнения, применяемые при запуске скрипта Robo:strict– если задано значениеtrue, скрипт Robo не использует частичное соответствие, пропуск текущего действия и приостановку. То есть скрипт Robo выполняется как обычный инструментальный тест и завершается с ошибкой, как только какое-либо из его действий не удается выполнить. По умолчанию задано значениеfalse.dismiss_popups– если задано значениеtrue, автоматизированное тестирование закрывает все неожиданные диалоговые окна во время выполнения скрипта автоматизированного тестирования даже в режимеstrict. Этот параметр не действует, если не включен режимstrict. По умолчанию используется значениеfalse.notify– если задано значениеfalse, скрипт Robo не показывает уведомления на экране в начале и конце выполнения. По умолчанию задано значениеtrue.
postscript– параметры выполнения, применяемые после завершения скрипта Robo:terminate– если задано значениеtrue, автоматизированное тестирование Robo прекращается после выполнения скрипта Robo. По умолчанию используется значениеfalse.
Ниже приведен пример скрипта Robo, выполненного в режиме strict без уведомлений на экране. Скрипт ждет три секунды, после чего сканирование останавливается:
"roboscript": {
"executionMode": {
"strict": true,
"notify": false
},
"postscript": {
"terminate": true
}
}
[
{
"eventType": "WAIT",
"delayTime": 3000
}
]
Параметры шаблона
Параметр шаблона – это плейсхолдер в скрипте 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 достиг maxNumberOfRuns, он больше не может быть запущен в рамках определенного сканирования. Если в текущем контексте можно запустить несколько скриптов автоматизированного тестирования, приоритет определяется в следующем порядке:
- Содержит атрибут "тип устройства"
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 запускает скрипт не более одного раза за сканирование. Это можно сделать с помощью атрибута maxNumberOfRuns.
Ниже приведен пример скрипта Robo, который переводит тестируемое приложение в фоновый режим до 10 раз:
{
"id": 1000,
"maxNumberOfRuns": 10,
"contextDescriptor": {
"condition": "app_under_test_shown"
},
"actions": [
{
"eventType": "GO_HOME"
}
]
}
Этап сканирования
Скрипты Robo можно применять на разных этапах сканирования:
| Этап сканирования | Описание |
pre_crawl
|
До запуска автоматизированного тестирования и начала сканирования тестируемого приложения. |
post_crawl
|
После того как автоматизированное тестирование завершит сканирование тестируемого приложения. Скрипт Robo post_crawl не должен длиться более 15 секунд, иначе сканирование может завершиться по тайм-ауту.
|
crawl
|
Основной этап сканирования, когда робот сканирует тестируемое приложение. |
close_screen
|
Когда робот пытается вернуться с определенного экрана, он исследует все возможные действия на этом экране. По умолчанию Robo нажимает кнопку "Назад", что нежелательно в некоторых сценариях. |
Если атрибут crawlStage в скрипте Robo не указан, подразумевается, что он имеет значение crawl.
Ниже приведен пример скрипта Robo, который удаляет данные пользователя тестируемого приложения до того, как Robo начнет его сканировать:
{
"id": 1000,
"crawlStage": "pre_crawl",
"actions": [
{
"eventType": "ADB_SHELL_COMMAND",
"command": "pm clear __%APP_PACKAGE_NAME%__"
}
]
}
Ниже приведен пример скрипта 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 выполняются в следующем порядке:
Робот проверяет, отображается ли на экране нужный ребенок, выполняя позиционирование в содержащем RecyclerView или AdapterView.
Робо-тест выполняет записанное действие непосредственно с дочерним элементом, поскольку он уже отображается на экране.
Ниже приведен пример действия при клике на дочерний элемент 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 вместе с приложением и запустить тестирование.
Если к автоматизированному тестированию прикреплен скрипт, автоматизированное тестирование сначала выполняет действия из этого скрипта, а затем – стандартную проверку.
Чтобы создать 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"
|
Используется в инструменте записи скриптов автоматизированного тестирования в Android Studio для нажатия на элементы списка. |
elementDescriptors
|
Определяет виджет интерфейса, на который нажал пользователь, с помощью иерархии интерфейса Android.
Несовместимо с visionText.
|
visionText
|
Определяет элемент, на который нажал пользователь, с помощью оптического распознавания символов. Несовместимо с elementDescriptors.
|
matchIndex
|
Указывает индекс экземпляра целевого элемента, если он был найден с помощью visionText. Если это 0, действие скрипта Robo выбирает первый подходящий элемент, если 1 – второй и т. д. Порядок определяется слева направо и сверху вниз. Значение по умолчанию – 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", обнаруженное на экране с помощью оптического распознавания символов:
{
"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 в Android Studio для обеспечения обратной совместимости с Espresso Test Recorder. Автоматизированное тестирование предоставляет тестируемому приложению все разрешения в начале каждого сканирования, поэтому это действие не имеет эффекта. НЕ используйте его в скриптах автоматизированного тестирования.
В таблице ниже перечислены обязательные атрибуты.
| Атрибут | Описание |
"eventType": "PERMISSIONS_REQUEST"
|
-- |
Как игнорировать все элементы на экране
В результате Robo будет игнорировать все элементы на любом экране, который запускает содержащий скрипт Robo.
В таблице ниже перечислены обязательные атрибуты.
| Атрибут | Описание |
"eventType": "ALL_ELEMENTS_IGNORED"
|
-- |
Ниже приведен пример действия скрипта автоматизированного тестирования, которое заставляет Robo игнорировать все элементы на экране:
{
"eventType": "ALL_ELEMENTS_IGNORED"
}
Как игнорировать элемент
После этого действия автоматизированное тестирование будет игнорировать элемент или элементы, соответствующие указанному селектору 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
|
Определяет элемент, на который было выполнено долгое нажатие, с помощью оптического распознавания символов. Несовместимо с elementDescriptors.
|
matchIndex
|
Указывает индекс экземпляра целевого элемента, если он был найден с помощью visionText. Если это 0, действие скрипта Robo выбирает первый подходящий элемент, если 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.
Ниже приведен пример действия, выполняемого с помощью жеста одним пальцем в скрипте 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"
|
Используется в инструменте записи скриптов автоматизированного тестирования в Android Studio для нажатия кнопки "Назад" в эмуляторах с API 28. |
Ниже приведен пример действия скрипта Robo, которое нажимает кнопку "Назад":
{
"eventType": "PRESSED_BACK"
}
Нажмите кнопку главного экрана
На устройство будет отправлено событие KEYCODE_HOME.
В таблице ниже перечислены обязательные атрибуты.
| Атрибут | Описание |
"eventType": "GO_HOME"
|
-- |
Ниже приведен пример действия скрипта Robo, которое нажимает кнопку "Домой":
{
"eventType": "GO_HOME"
}
Как прокрутить элемент в видимую область
В результате этого действия робот прокручивает вперед виджет интерфейса, соответствующий значению 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 подождать, пока элемент не появится на экране, в течение указанного времени.
В таблице ниже перечислены обязательные атрибуты.
| Атрибут | Описание |
"eventType": "WAIT_FOR_ELEMENT"
|
-- |
delayTime
|
Указывает время ожидания в миллисекундах. |
elementDescriptors
|
Определяет ожидаемый виджет интерфейса с помощью иерархии интерфейса Android. |
Ниже приведен пример действия скрипта Robo, которое ожидает появления на экране виджета интерфейса с идентификатором ресурса "my.app.package:id/confirmation_button" в течение 30 секунд:
{
"eventType": "WAIT_FOR_ELEMENT",
"delayTime": 30000,
"elementDescriptors": [
{
"resourceId": "my.app.package:id/confirmation_button"
}
]
}
Дальнейшие действия
- Подробнее о том, как запустить скрипт Robo…