В этом документе содержится справочная информация о робот-скриптах, включая их структуру, возможности, использование, запись и действия. Робо-скрипты – это тесты, которые автоматизируют ручные задачи по обеспечению качества мобильных приложений и позволяют использовать стратегии непрерывной интеграции и тестирования перед запуском. Робо-скрипт – это 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-скриптов. Синтаксис Robo-скриптов для iOS+ идентичен синтаксису для Android, а поддерживаемые функции iOS+ работают аналогично своим аналогам для Android.
В iOS+ поддерживаются следующие действия:
- Утверждение
- Клик
- Нажатие и удержание
- Пролистните
- Игнорировать все элементы
- Пауза
- Сделать скриншот
- Прекратить сканирование
В iOS+ поддерживаются следующие идентифицирующие атрибуты в дескрипторах элементов:
- Название курса
- Название класса предка
- Описание контента (и регулярное выражение)
- Текст (и регулярное выражение)
В iOS+ поддерживаются следующие условия активации в дескрипторах контекста:
- Показано тестируемое приложение
- Затронутая область
- Выполнено действие, не относящееся к скрипту Robo
Структура
У робо-скрипта есть несколько атрибутов, которые описывают, как робот его выполняет. Большинство этих атрибутов необязательны и имеют значения по умолчанию:
| Атрибут | Описание |
id
|
Целое число, которое помогает отслеживать этот скрипт автоматизированного тестирования в результатах сканирования.
В автоматизированном тестировании есть встроенные скрипты со своими id. Хотя одинаковые значения id в разных скриптах Robo не влияют на их поведение, вам может быть сложно различать действия из этих скриптов Robo в результатах сканирования. Чтобы избежать конфликтов, рекомендуем присвоить робот-скриптам уникальное значение id, равное 1000 или выше.
|
description
|
Похоже на id, но более описательно.
|
crawlStage
|
Этап сканирования, на котором применяется скрипт автоматизированного тестирования. По умолчанию это основной этап сканирования. |
priority
|
Приоритет этого робот-скрипта по сравнению с другими.
По умолчанию у всех робот-скриптов приоритет равен 1.
|
maxNumberOfRuns
|
Указывает, сколько раз за одно сканирование робот может выполнить этот скрипт. По умолчанию автоматизированное тестирование может выполнить скрипт один раз. |
contextDescriptor
|
Описывает контекст или условие, которое запускает этот робот-скрипт. Если условие запуска не указано, оно считается выполненным. Другими словами, скрипт автоматизированного тестирования выполняется без условий. |
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.
|
Ниже приведен пример 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"
}
]
}
]
}
Ниже приведен пример робо-скрипта, который запускается, когда оптическое распознавание символов (OCR) обнаруживает "Privacy Policy".
{
"id": 1000,
"description": "Vision text Robo script",
"contextDescriptor": {
"condition": "element_present",
"visionText": "Privacy Policy"
},
"actions": [
{
"eventType": "VIEW_CLICKED",
"visionText": "Privacy Policy"
}
]
}
Ниже приведен пример робот-скрипта, который ожидает пять секунд после каждого действия, не относящегося к скрипту.
{
"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%__– название пакета тестируемого приложения.
Ниже приведен пример скрипта 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 со стандартными действиями автоматизированного тестирования. Этот метод подходит для случаев, когда приложение работает нестабильно или когда изменения между версиями приложения достаточно велики, чтобы автоматизированное тестирование могло "заполнить пробелы" стандартными действиями. |
Приоритеты.
Если робот-скрипт достигнет maxNumberOfRuns, он больше не будет запускаться при сканировании. Если в текущем контексте может быть запущено несколько робот-скриптов, приоритет отдается тому, который:
- Содержит атрибут
contextDescriptor. - Имеет наивысший
priority(по умолчанию все робо-скрипты имеют одинаковыйpriorityвыполнения, равный1). - Если приоритеты скриптов одинаковы, то этот скрипт будет первым в списке.
Ниже приведен пример файла с тремя 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 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, который заставляет робота нажимать "Cancel" при попытке вернуться из диалогового окна подтверждения.
{
"id": 1000,
"crawlStage": "close_screen",
"maxNumberOfRuns": 999,
"contextDescriptor": {
"condition": "element_present",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/confirmation_dialog"
}
]
},
"actions": [
{
"eventType": "VIEW_CLICKED",
"elementDescriptors": [
{
"text": "Cancel"
}
]
}
]
}
Действия, выполняемые при определенных условиях
Робо-скрипт может содержать условные действия. У действий, выполняемых при определенных условиях, есть три дополнительных атрибута, которые описывают, как робот их выполняет:
| Атрибут | Описание |
priority
|
Приоритет этого условного действия по сравнению с другими условными действиями в содержащем его робот-скрипте. По умолчанию всем условным действиям присваивается приоритет 1.
|
maxNumberOfRuns
|
Сколько раз это условное действие может быть выполнено в течение одного выполнения содержащего его Robo-скрипта. По умолчанию все условные действия могут выполняться не более одного раза за одно выполнение содержащего их Robo-скрипта. |
contextDescriptor
|
Контекст или условие, которое запускает это условное действие. Он имеет ту же структуру и предлагает аналогичные возможности, что и contextDescriptor робо-скрипта. |
При запуске скрипт автоматизированного тестирования выполняет безусловные действия одно за другим в порядке их появления. Если в робот-скрипте есть условные действия, они учитываются каждый раз перед выбором безусловного действия. Если условное действие активировано и выбрано на основе его приоритета и оставшегося количества запусков, то робот-скрипт выполняет это условное действие. В противном случае автоматизированное тестирование выполняет следующее безусловное действие. Чтобы скрипт автоматизированного тестирования был действительным, он должен содержать хотя бы одно безусловное действие.
Ниже приведен пример безусловного скрипта автоматизированного тестирования с условным действием, которое закрывает всплывающие диалоговые окна, если они появляются в любой момент во время выполнения скрипта автоматизированного тестирования.
{
"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 игнорировать все виджеты пользовательского интерфейса на экране, содержащем виджет с идентификатором ресурса "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 загружаются динамически и могут отображаться на экране, который находится далеко от текущего. Поскольку размер экрана и количество пролистываний, необходимых для перехода к этому дочернему элементу, различаются для разных форм-факторов устройств, гораздо надежнее полагаться на позицию данных дочернего элемента, которая является абсолютной. Полагаться на количество свайпов, необходимых для вывода этого дочернего элемента на экран, а затем использовать его положение на экране – менее надежный подход.
Поэтому робот-скрипт фиксирует абсолютные позиции дочерних элементов RecyclerView, которые являются целями действий робота-скрипта, как 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 будет остановлено из-за ошибки утверждения.
В таблице ниже перечислены обязательные атрибуты.
| Атрибут | Описание |
"eventType": "ASSERTION"
|
-- |
contextDescriptor
|
Описывает заявленный контекст или условие. Он имеет ту же структуру и предлагает аналогичные возможности, что и contextDescriptor робот-скрипта. |
Ниже приведен пример утверждения в робо-скрипте, которое проверяет, что тестируемое приложение находится на переднем плане:
{
"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.
|
Ниже приведен пример действия скрипта Robo, который нажимает кнопку с идентификатором ресурса "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-скрипта не выполняется. По умолчанию это пустая строка, то есть выходные данные не проверяются.
Ниже приведен пример действия скрипта Robo, которое очищает пользовательские данные тестируемого приложения.
{
"eventType": "ADB_SHELL_COMMAND",
"command": "pm clear __%APP_PACKAGE_NAME%__"
}
Назначить права доступа
Это действие записывается регистратором скриптов Robo в Android Studio для обратной совместимости с Espresso Test Recorder. В начале каждого сканирования автоматизированное тестирование предоставляет тестируемому приложению все разрешения, поэтому это действие не выполняется. НЕ используйте его в своих скриптах.
В таблице ниже перечислены обязательные атрибуты.
| Атрибут | Описание |
"eventType": "PERMISSIONS_REQUEST"
|
-- |
Игнорировать все элементы на экране
В результате робот будет игнорировать все элементы на любом экране, который запускает содержащий его скрипт.
В таблице ниже перечислены обязательные атрибуты.
| Атрибут | Описание |
"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. |
Ниже приведен пример действия в автоматизированном тестировании, которое перемещает ползунок вправо:
{
"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. |
Ниже приведен пример действия в робот-скрипте, которое ожидает появления на экране виджета пользовательского интерфейса с идентификатором ресурса "my.app.package:id/confirmation_button" в течение 30 секунд.
{
"eventType": "WAIT_FOR_ELEMENT",
"delayTime": 30000,
"elementDescriptors": [
{
"resourceId": "my.app.package:id/confirmation_button"
}
]
}
Дальнейшие действия
- Подробнее о том, как запустить автоматизированное тестирование.