В этом документе содержится справочная информация о робот-скриптах, включая их структуру, возможности, использование, запись и действия. Робо-скрипты – это тесты, которые автоматизируют ручные задачи по обеспечению качества мобильных приложений и позволяют использовать стратегии непрерывной интеграции и тестирования перед запуском. Робо-скрипт – это JSON-файл, в котором описана последовательность действий в пользовательском интерфейсе и других действий.
Создать робот-скрипт можно следующими способами:
Используйте функцию записи робот-скрипта. (только для Android)
Создайте робот-скрипт вручную. (Android и iOS+)
Запишите робот-скрипт и отредактируйте его вручную. (только для Android)
Подробнее о том, как использовать робот-скрипты…
Введение
Скрипт Robo предоставляется для автоматизированного тестирования вместе с другими входными данными, такими как пакет приложения Android (APK).
Ниже приведен пример робо-скрипта, который выполняет вход пользователя в приложение и запускается при открытии тестируемого приложения.
[
{
"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"
}
]
}
]
}
]
Если в файле только один робот-скрипт и у него условие запуска по умолчанию app_under_test_shown, как в примере выше, то вы можете указать робот-скрипт в файле, используя более простой формат – просто как последовательность его действий:
[
{
"eventType": "VIEW_TEXT_CHANGED",
"replacementText": "user123",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/username"
}
]
},
{
"eventType": "VIEW_TEXT_CHANGED",
"replacementText": "12345",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/password"
}
]
},
{
"eventType": "VIEW_CLICKED",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/login"
}
]
}
]
Поддержка автоматизированного тестирования с помощью скриптов в iOS+
В Robo для iOS+ (бета) ограничена поддержка робо-скриптов. Синтаксис Robo-скриптов для iOS+ идентичен синтаксису для Android, а поддерживаемые функции iOS+ работают аналогично своим аналогам для Android.
В iOS+ поддерживаются следующие действия:
- Утверждение
- Клик
- Нажатие и удержание
- Пролистните
- Игнорировать все элементы
- Пауза
- Сделать скриншот
- Прекратить сканирование
В iOS+ поддерживаются следующие идентифицирующие атрибуты в дескрипторах элементов:
- Название курса
- Название класса предка
- Описание контента (и регулярное выражение)
- Текст (и регулярное выражение)
В iOS+ поддерживаются следующие условия активации в дескрипторах контекста:
- Показано тестируемое приложение
- Элемент присутствует
- Выполнено действие, не относящееся к скрипту автоматизированного тестирования
Структура
У робо-скрипта есть несколько атрибутов, которые описывают, как он выполняется. Большинство этих атрибутов необязательны и имеют значения по умолчанию:
| Атрибут | Описание |
id
|
Целое число, которое помогает отслеживать этот скрипт автоматизированного тестирования в результатах сканирования.
В Robo есть встроенные скрипты со своими id. Хотя одинаковые значения id в разных робот-скриптах не влияют на их поведение, различать действия из этих скриптов в результатах сканирования может быть сложно. Чтобы избежать конфликтов, рекомендуем присвоить скриптам автоматизированного тестирования уникальный номер id, равный 1000 или выше.
|
description
|
Похоже на id, но более описательно.
|
crawlStage
|
Этап сканирования, на котором применяется скрипт автоматизированного тестирования. По умолчанию это основной этап сканирования. |
priority
|
Приоритет этого робот-скрипта по сравнению с другими.
По умолчанию у всех робот-скриптов приоритет равен 1.
|
maxNumberOfRuns
|
Указывает, сколько раз за одно сканирование робот может выполнить этот скрипт. По умолчанию автоматизированное тестирование может выполнить скрипт один раз. |
contextDescriptor
|
Описывает контекст или условие, которое запускает этот Robo-скрипт. Если условие запуска этого скрипта автоматизированного тестирования не указано, оно считается выполненным всегда. Другими словами, скрипт выполняется безусловно. |
actions
|
Все действия этого робо-скрипта. |
Один файл содержит набор из одного или нескольких скриптов автоматизированного тестирования.
Ниже приведен пример файла с двумя безусловными скриптами 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"
|
Всегда запускает автоматизированное тестирование. |
"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, чтобы запускать робот-скрипт после каждых nonRoboscriptActionCount действий робота. По умолчанию это 1.
|
Ниже приведен пример робо-скрипта, который запускается, когда на экране появляется виджет пользовательского интерфейса с идентификатором ресурса "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"
}
]
}
]
}
Ниже приведен пример робо-скрипта, который запускается, когда оптическое распознавание символов (OCR) обнаруживает "Privacy Policy".
{
"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" : "WAIT",
"delayTime" : 5000
}]
}
Действия
Каждое действие в скрипте автоматизированного тестирования представлено в виде набора из одной или нескольких пар "атрибут – значение", которые описаны в таблице ниже.
| Атрибут | Описание |
eventType
|
Указывает тип действия, например клик, редактирование текста и т. д. Обязательно для каждого действия. |
elementDescriptors
|
Дескрипторы, идентифицирующие виджет пользовательского интерфейса. Обязательно для всех действий, у которых есть целевой виджет интерфейса, например нажатие определенной кнопки. |
optional
|
Если задано значение true, это действие пропускается, когда его невозможно выполнить. Например, это действие пропускается, если оно не может найти целевой виджет пользовательского интерфейса на экране, при этом содержащий скрипт Robo не завершается с ошибкой. Значение по умолчанию – false.
|
replacementText
|
Текст, который нужно ввести в целевой виджет пользовательского интерфейса. Обязательно для действий текстового редактора. |
swipeDirection
|
Указывает направление пролистывания. Обязательно для жестов пролистывания. |
delayTime
|
Указывает время ожидания в миллисекундах. Обязательно для действий ожидания. |
pointTapXCoordinate и pointTapYCoordinate
|
Координаты X и Y точки нажатия в пикселях. Взаимоисключающий с pointTapXPercent и pointTapYPercent.
Обязательно для действий по нажатию на точку.
|
pointTapXPercent и pointTapYPercent
|
Процентные координаты X и Y точки касания. Взаимоисключающий с pointTapXCoordinate и pointTapYCoordinate. Обязательно для действий по нажатию на точку.
|
Ниже приведен пример робот-скрипта с двумя действиями без целевых виджетов пользовательского интерфейса. Это означает, что эти действия не выполняются в определенном виджете пользовательского интерфейса:
[
{
"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 действия содержит последовательность дескрипторов элементов, упорядоченных таким образом, что первый соответствует целевому виджету пользовательского интерфейса, второй – родительскому виджету целевого виджета пользовательского интерфейса и т. д. Целевой виджет действия считается найденным, если все его дескрипторы элементов соответствуют дочерней иерархии виджета.
Ниже приведен пример робот-скрипта с изменением текста и действиями клика. В обоих случаях вам нужно идентифицировать целевой виджет пользовательского интерфейса с помощью предоставленных дескрипторов элементов.
[
{
"eventType": "VIEW_TEXT_CHANGED",
"replacementText": "John",
"elementDescriptors": [
{
"className": "android.support.v7.widget.AppCompatEditText",
"groupViewChildPosition": 0,
"resourceId": "com.google.samples.apps.topeka:id/first_name"
},
{
"className": "android.widget.FrameLayout",
"groupViewChildPosition": 0
},
{
"className": "android.support.design.widget.TextInputLayout",
"groupViewChildPosition": 1
}
]
},
{
"eventType": "VIEW_CLICKED",
"elementDescriptors": [
{
"className": "android.support.design.widget.FloatingActionButton",
"groupViewChildPosition": 1,
"resourceId": "com.google.samples.apps.topeka:id/done"
},
{
"className": "android.widget.FrameLayout",
"groupViewChildPosition": 1,
"resourceId": "com.google.samples.apps.topeka:id/content"
},
{
"className": "android.widget.FrameLayout",
"groupViewChildPosition": 0,
"resourceId": "com.google.samples.apps.topeka:id/sign_in_content"
}
]
}
]
Варианты выполнения
Вы можете добавить перед списком действий в робот-скрипте объект JSON, который задает параметры выполнения этого скрипта. Этот заголовок начинается с ключевого слова roboscript, за которым следует JSON-представление нужных параметров выполнения.
Для робот-скриптов поддерживаются следующие варианты выполнения:
executionMode– параметры, которые применяются при выполнении скрипта автоматизированного тестирования:strict– если задано значениеtrue, скрипт автоматизированного тестирования не использует частичное совпадение, пропуск текущего действия и приостановку. Это значит, что скрипт Robo выполняется как обычный инструментальный тест и завершается с ошибкой, если какое-либо из его действий не может быть выполнено. По умолчанию этоfalse.dismiss_popups– если задано значениеtrue, автоматизированное тестирование закрывает все неожиданные диалоговые окна во время выполнения скрипта даже в режимеstrict. Этот параметр не действует, если не включен режимstrict. По умолчанию этоfalse.notify– если задано значениеfalse, скрипт автоматизированного тестирования не показывает уведомления на экране в начале и конце выполнения. По умолчанию используетсяtrue.
postscript– параметры выполнения, которые применяются после завершения скрипта автоматизированного тестирования:terminate– если задано значениеtrue, автоматизированное тестирование прекращается после выполнения скрипта. По умолчанию этоfalse.
Ниже приведен пример робот-скрипта, который выполняется в режиме strict без уведомлений на экране. Он ожидает три секунды, после чего сканирование прекращается.
"roboscript": {
"executionMode": {
"strict": true,
"notify": false
},
"postscript": {
"terminate": true
}
}
[
{
"eventType": "WAIT",
"delayTime": 3000
}
]
Параметры шаблона
Параметр шаблона – это плейсхолдер в скрипте автоматизированного тестирования, который заменяется фактическим значением, когда автоматизированное тестирование загружает этот скрипт для выполнения. Параметры шаблона начинаются с двойного подчеркивания и знака процента, а заканчиваются знаком процента и двойным подчеркиванием.
Робо-скрипты поддерживают следующий параметр шаблона:
__%APP_PACKAGE_NAME%__– название пакета тестируемого приложения.
Ниже приведен пример скрипта автоматизированного тестирования, который останавливает процесс тестируемого приложения.
[
{
"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 со стандартными действиями автоматизированного тестирования. Этот метод подходит для сценариев, когда поведение приложения нестабильно или когда изменения между версиями приложения достаточно велики, чтобы автоматизированное тестирование могло "заполнить пробелы" своими стандартными действиями. |
Приоритеты
Если робот-скрипт достигнет maxNumberOfRuns, он больше не будет запускаться в рамках текущего сканирования. Если в текущем контексте может быть запущено несколько робот-скриптов, приоритет отдается тому, который:
- Содержит атрибут
contextDescriptor. - Имеет наивысший
priority(по умолчанию все робот-скрипты имеют одинаковыйpriorityвыполнения, равный1). - Если приоритеты робот-скриптов одинаковы, то в списке он будет указан раньше других.
Ниже приведен пример файла с тремя робо-скриптами, которые выполняют одно и то же действие и запускаются при одном и том же условии – тестируемое приложение находится на переднем плане:
[
{
"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 script 3"как последний применимый скрипт автоматизированного тестирования.
Повторяющиеся запуски
По умолчанию автоматизированное тестирование запускает скрипт не более одного раза за сканирование. Это можно сделать с помощью атрибута maxNumberOfRuns.
Ниже приведен пример скрипта автоматизированного тестирования, который переводит тестируемое приложение в фоновый режим до 10 раз.
{
"id": 1000,
"maxNumberOfRuns": 10,
"contextDescriptor": {
"condition": "app_under_test_shown"
},
"actions": [
{
"eventType": "GO_HOME"
}
]
}
Этап сканирования
Робо-скрипты можно применять на разных этапах сканирования:
| Этап сканирования | Описание |
pre_crawl
|
Перед запуском автоматизированного тестирования и сканированием приложения. |
post_crawl
|
После того как автоматизированное тестирование закончит сканирование тестируемого приложения. Продолжительность выполнения скрипта post_crawl не должна превышать 15 секунд, иначе сканирование может быть прервано из-за тайм-аута.
|
crawl
|
Основной этап сканирования, на котором робот сканирует тестируемое приложение. |
close_screen
|
Когда автоматизированное тестирование пытается вернуться с определенного экрана, на котором он уже выполнил все возможные действия. По умолчанию автоматизированное тестирование нажимает кнопку "Назад", что нежелательно в некоторых сценариях. |
Если атрибут crawlStage робот-скрипта не указан, подразумевается, что он равен crawl.
Ниже приведен пример скрипта 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 их выполняет:
| Атрибут | Описание |
priority
|
Приоритет этого условного действия по сравнению с другими условными действиями в скрипте автоматизированного тестирования. По умолчанию всем условным действиям присваивается приоритет 1.
|
maxNumberOfRuns
|
Сколько раз это условное действие может быть выполнено за один запуск содержащего его Robo-скрипта. По умолчанию все условные действия могут выполняться не более одного раза за одно выполнение содержащего их робо-скрипта. |
contextDescriptor
|
Контекст или условие, при котором запускается это условное действие. Он имеет ту же структуру и предлагает те же возможности, что и contextDescriptor в скрипте автоматизированного тестирования. |
При запуске скрипт автоматизированного тестирования выполняет безусловные действия одно за другим в порядке их появления. Если скрипт автоматизированного тестирования содержит условные действия, они учитываются каждый раз перед выбором безусловного действия. Если срабатывает условное действие и оно выбирается на основе приоритета и оставшегося количества запусков, то робот-скрипт выполняет это условное действие. В противном случае автоматизированное тестирование выполняет следующее безусловное действие. Чтобы скрипт автоматизированного тестирования был действительным, он должен содержать хотя бы одно безусловное действие.
Ниже приведен пример безусловного скрипта 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 можно указать, какие виджеты интерфейса или экраны нужно игнорировать. Эти инструкции представлены как игнорирование "действий" с помощью eventType ELEMENT_IGNORED и ALL_ELEMENTS_IGNORED соответственно.
Если атрибут contextDescriptor скрипта Robo, содержащего действия игнорирования, совпадает с заданным экраном, Robo не взаимодействует с виджетами пользовательского интерфейса, на которые нацелены его действия игнорирования (если только какое-либо другое действие скрипта Robo не заставляет Robo выполнить действие с одним из игнорируемых виджетов пользовательского интерфейса).
В одном робо-скрипте могут быть действия всех трех типов. В отличие от других действий в робот-скриптах, игнорирование действий применяется, пока contextDescriptor робот-скрипта, в котором они содержатся, соответствует экрану во время сканирования роботом, независимо от значений атрибутов 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. Робо-скрипт также фиксирует абсолютные позиции данных дочерних элементов AdapterView, которые являются целями действий робо-скрипта, как 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-файл скрипта автоматизированного тестирования в Android Studio, следуйте инструкциям в статье Как записать скрипт автоматизированного тестирования с помощью Test Lab в Android Studio.
Действия робот-скрипта
Следующий общий необязательный атрибут применяется ко всем действиям:
description– помогает отслеживать выполнение этого действия в выходных данных автоматизированного тестирования.
Утверждение
Если условие выполняется, Robo-скрипт переходит к следующему действию, которое может быть ещё одной проверкой. В противном случае выполнение скрипта Robo будет остановлено из-за ошибки утверждения.
В таблице ниже перечислены обязательные атрибуты.
| Атрибут | Описание |
"eventType": "ASSERTION"
|
-- |
contextDescriptor
|
Описывает контекст или условие. Он имеет ту же структуру и предлагает те же возможности, что и contextDescriptor робо-скрипта. |
Ниже приведен пример утверждения в 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" с помощью оптического распознавания символов:
{
"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"
|
Используется средством записи скриптов автоматизированного тестирования в Android Studio для нажатия на элементы списка. |
elementDescriptors
|
Определяет виджет, на который нажал пользователь, с помощью иерархии интерфейса Android.
Несовместимо с visionText.
|
visionText
|
Определяет элемент, на который нажали, с помощью оптического распознавания символов. Несовместимо с elementDescriptors.
|
matchIndex
|
Указывает индекс вхождения целевого элемента, если он идентифицируется с помощью visionText. Если указано значение 0, действие скрипта Robo выбирает первый соответствующий элемент, если 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", обнаруженное на экране с помощью оптического распознавания символов.
{
"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. Если вывод не совпадает, действие автоматизированного тестирования не выполняется. По умолчанию это пустая строка, то есть выходные данные не проверяются.
Ниже приведен пример действия скрипта 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"
|
-- |
Ниже приведен пример действия скрипта автоматизированного тестирования, которое заставляет автоматизированное тестирование игнорировать все элементы на экране.
{
"eventType": "ALL_ELEMENTS_IGNORED"
}
Как игнорировать элемент
Это действие заставляет автоматизированное тестирование игнорировать элемент (или элементы), соответствующие указанному elementDescriptors.
В таблице ниже перечислены обязательные атрибуты.
| Атрибут | Описание |
"eventType": "ELEMENT_IGNORED"
|
-- |
elementDescriptors
|
Определяет игнорируемые виджеты пользовательского интерфейса с помощью иерархии пользовательского интерфейса Android. |
Следующий атрибут является необязательным:
ignoreChildren– если задано значениеtrue, автоматизированное тестирование также игнорирует всех потомков игнорируемых виджетов. По умолчанию это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
|
Определяет элемент, на который нажали и удерживали, с помощью оптического распознавания символов. Несовместимо с 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.
Ниже приведен пример действия с жестом в одной точке, которое выполняет пролистывание вниз:
{
"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. |
Ниже приведен пример действия робота-скрипта, которое выполняет действие 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"
|
Используется средством записи робо-скриптов в Android Studio для нажатия кнопки "Назад" в эмуляторах API 28. |
Ниже приведен пример действия в робо-скрипте, которое нажимает кнопку "Назад":
{
"eventType": "PRESSED_BACK"
}
Нажмите кнопку главного экрана
На устройство будет отправлено событие KEYCODE_HOME.
В таблице ниже перечислены обязательные атрибуты.
| Атрибут | Описание |
"eventType": "GO_HOME"
|
-- |
Ниже приведен пример действия автоматизированного тестирования, которое нажимает кнопку "Домой":
{
"eventType": "GO_HOME"
}
Как прокрутить элемент в видимую область
Это действие заставляет автоматизированное тестирование прокручивать вперед виджет пользовательского интерфейса, соответствующий указанному 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. |
Ниже приведен пример действия в Robo-скрипте, которое перемещает ползунок вправо:
{
"eventType": "POINT_TAP_ELEMENT",
"pointTapXPercent": 80,
"pointTapYPercent": 50,
"elementDescriptors": [
{
"resourceId": "my.app.package:id/my_seekbar"
}
]
}
Прекратить сканирование
Это действие останавливает автоматизированное тестирование.
В таблице ниже перечислены обязательные атрибуты.
| Атрибут | Описание |
|---|---|
"eventType": "TERMINATE_CRAWL"
|
-- |
Ниже приведен пример действия скрипта автоматизированного тестирования, которое останавливает автоматизированное тестирование.
{
"eventType": "TERMINATE_CRAWL"
}
Пауза
В таблице ниже перечислены обязательные атрибуты.
| Атрибут | Описание |
"eventType": "WAIT" (or "DELAYED_MESSAGE_POSTED")
|
-- |
delayTime
|
Указывает время ожидания в миллисекундах. |
Ниже приведен пример действия в робот-скрипте, которое ожидает три секунды:
{
"eventType": "WAIT",
"delayTime": 3000
}
Ожидание элемента
Это действие заставляет робота ждать появления элемента на экране в течение указанного времени.
В таблице ниже перечислены обязательные атрибуты.
| Атрибут | Описание |
"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"
}
]
}
Дальнейшие действия
- Подробнее о том, как запустить автоматизированное тестирование.