Справочное руководство по роботизированным сценариям

В этом документе содержится справочная информация о скриптах Robo, включая структуру, возможности, использование, запись и действия. Скрипты Robo — это тесты, которые автоматизируют ручные задачи обеспечения качества (QA) для мобильных приложений и позволяют реализовать стратегии непрерывной интеграции (CI) и предварительного тестирования. Скрипт Robo — это файл JSON, описывающий последовательность пользовательского интерфейса (UI) и других действий.

Создать Robo-скрипт можно следующими способами:

  • Используйте функцию записи скрипта Robo. (Только для Android)

  • Создайте скрипт Robo вручную. (Android и iOS+)

  • Запишите скрипт Robo, а затем отредактируйте его вручную. (Только для Android)

Дополнительную информацию об использовании скриптов Robo см. в разделе Запуск скрипта Robo .

Введение

Скрипт Robo предоставляется для тестирования Robo вместе с другими входными данными, такими как пакет тестируемого приложения Android (APK).

Ниже приведен пример скрипта Robo, который регистрирует пользователя в приложении и срабатывает при запуске тестируемого приложения:

[
  {
    "crawlStage": "crawl",
    "contextDescriptor": {
      "condition": "app_under_test_shown"
    },
    "actions": [
      {
        "eventType": "VIEW_TEXT_CHANGED",
        "replacementText": "user123",
        "elementDescriptors": [
          {
            "resourceId": "my.app.package:id/username"
          }
        ]
      },
      {
        "eventType": "VIEW_TEXT_CHANGED",
        "replacementText": "12345",
        "elementDescriptors": [
          {
            "resourceId": "my.app.package:id/password"
          }
        ]
      },
      {
        "eventType": "VIEW_CLICKED",
        "elementDescriptors": [
          {
            "resourceId": "my.app.package:id/login"
          }
        ]
      }
    ]
  }
]

Если в файле есть один скрипт Robo и у него есть условие срабатывания по умолчанию app_under_test_shown , как в примере выше, то вы можете указать скрипт Robo в файле, используя более простой формат — просто как последовательность его действий:

[
  {
    "eventType": "VIEW_TEXT_CHANGED",
    "replacementText": "user123",
    "elementDescriptors": [
      {
        "resourceId": "my.app.package:id/username"
      }
    ]
  },
  {
    "eventType": "VIEW_TEXT_CHANGED",
    "replacementText": "12345",
    "elementDescriptors": [
      {
        "resourceId": "my.app.package:id/password"
      }
    ]
  },
  {
    "eventType": "VIEW_CLICKED",
    "elementDescriptors": [
      {
        "resourceId": "my.app.package:id/login"
      }
    ]
  }
]

Поддержка iOS+ для скриптов Robo

Robo для iOS+ (Beta) имеет ограниченную поддержку скриптов Robo. Синтаксис скрипта Robo для iOS+ идентичен синтаксису Android, а поддерживаемые функции iOS+ ведут себя аналогично своим аналогам Android.

В iOS+ поддерживаются следующие действия:

  • Утверждение
  • Нажмите
  • Длительный щелчок
  • Проведите пальцем
  • Игнорировать все элементы
  • Ждать
  • Сделать снимок экрана
  • Прекратить сканирование

В iOS+ поддерживаются следующие идентифицирующие атрибуты в дескрипторах элементов:

  • Имя класса
  • Имя класса-предка
  • Описание контента (и регулярное выражение)
  • Текст (и регулярное выражение)

В iOS+ поддерживаются следующие условия срабатывания в контекстных дескрипторах :

  • Показано тестируемое приложение
  • Элемент присутствует
  • Выполнено действие не-роботизированного скрипта

Структура

Скрипт Robo имеет несколько атрибутов, которые описывают, как Robo его выполняет. Большинство этих атрибутов являются необязательными с предопределенными значениями по умолчанию:

Атрибут Описание
id Целое число, которое помогает отслеживать этот скрипт Robo в результатах сканирования. Robo имеет встроенные скрипты Robo со своими собственными id . Хотя один и тот же id в разных скриптах Robo не влияет на их поведение, различение действий из этих скриптов Robo в результатах сканирования может быть сложной задачей. Мы рекомендуем назначать вашим скриптам Robo уникальный id 1000 или выше, чтобы избежать конфликтов.
description Похож на id , но более описательный.
crawlStage Этап сканирования Robo применяет этот скрипт Robo на. По умолчанию это основной этап сканирования.
priority Приоритет этого скрипта Robo по сравнению с другими скриптами Robo. По умолчанию все скрипты Robo имеют приоритет 1 .
maxNumberOfRuns Указывает, сколько раз во время сканирования Robo может выполнить этот скрипт Robo. По умолчанию Robo может выполнить скрипт Robo один раз.
contextDescriptor Описывает контекст или условие, которое запускает этот скрипт Robo. Если опущено, условие запуска этого скрипта Robo считается всегда выполненным; другими словами, скрипт Robo является безусловным.
actions Все действия этого скрипта Robo.

Один файл содержит набор из одного или нескольких скриптов Robo.

Ниже приведен пример файла с двумя безусловными скриптами Robo, каждый из которых содержит одно действие, выполняемое один раз в начале сканирования:

[
  {
    "id": 1000,
    "description": "My first Robo script",
    "actions": [
      {
        "eventType": "DISABLE_KEYBOARD"
      }
    ]
  },
  {
    "id": 1001,
    "description": "My second Robo script",
    "actions": [
      {
        "eventType": "PRESSED_BACK"
      }
    ]
  }
]

Контекстный дескриптор

Контекстный дескриптор определяет контекст или условие, которое запускает скрипт Robo, используя один или комбинацию нескольких атрибутов:

Атрибут Описание
"condition": "always" Всегда запускает скрипт Robo.
"condition": "element_present" Проверяет, присутствует ли на экране виджет пользовательского интерфейса, соответствующий elementDescriptors или тексту, указанному visionText .
"condition": "element_disabled" Проверяет, присутствует ли на экране виджет пользовательского интерфейса, соответствующий elementDescriptors , и невозможно ли с ним взаимодействовать.
"condition": "element_checked" Проверяет, присутствует ли на экране виджет пользовательского интерфейса, соответствующий elementDescriptors , и отмечен ли он.
"condition": "app_under_test_shown" Проверяет, запущено ли тестируемое приложение на переднем плане.
"condition": "default_launcher_shown" Проверяет, отображается ли домашний экран устройства, что означает, что на переднем плане не запущено ни одного приложения.
"condition": "non_roboscript_action_performed" Проверяет, что последние nonRoboscriptActionCount последовательные действия, выполненные тестом Robo, не являются действиями скрипта Robo.
negateCondition Если установлено значение true , то condition отменяется. Например, вы можете использовать этот атрибут для проверки того, что виджет пользовательского интерфейса НЕ присутствует на экране или что тестируемое приложение НЕ работает на переднем плане.
elementDescriptors Один или несколько дескрипторов элементов, которые идентифицируют виджет пользовательского интерфейса на экране. Используется в сочетании с условиями element_present , element_disabled и element_checked . Взаимоисключающие с visionText . Для получения дополнительной информации см. раздел Дескрипторы элементов .
visionText Текст на экране распознается с помощью API оптического распознавания символов (OCR). visionText используется в сочетании с условием element_present . Взаимоисключающее с elementDescriptors .
nonRoboscriptActionCount Количество последовательных действий не-Robo-скрипта, выполненных ранее. Используется в сочетании с условием non_roboscript_action_performed для запуска Robo-скрипта после каждых nonRoboscriptActionCount действий Robo. По умолчанию это 1 .

Ниже приведен пример скрипта Robo, который запускается виджетом пользовательского интерфейса с идентификатором ресурса "my.app.package:id/page_header" присутствующим на экране:

{
  "id": 1000,
  "contextDescriptor": {
    "condition": "element_present",
    "elementDescriptors": [
      {
        "resourceId": "my.app.package:id/page_header"
      }
    ]
  },
  "actions": [
    {
      "eventType": "VIEW_CLICKED",
      "elementDescriptors": [
        {
          "text": "Settings"
        }
      ]
    }
  ]
}

Ниже приведен пример скрипта Robo, который запускается "Privacy Policy" обнаруженной с помощью оптического распознавания символов (OCR):

{
  "id": 1000,
  "description": "Vision text Robo script",
  "contextDescriptor": {
    "condition": "element_present",
    "visionText": "Privacy Policy"
  },
  "actions": [
    {
      "eventType": "VIEW_CLICKED",
      "visionText": "Privacy Policy"
    }
  ]
}

Ниже приведен пример скрипта Robo, который ждет 5 секунд после каждого действия Robo, не являющегося скриптом:

{
  "contextDescriptor": {
    "condition": "non_roboscript_action_performed"
  },
  "maxNumberOfRuns" : 1000,
  "actions" : [
    {
      "eventType" : "WAIT",
      "delayTime" : 5000
    }]
}

Действия

Каждое действие в скрипте Robo представлено в виде набора из одной или нескольких пар «атрибут-значение», которые описаны в следующей таблице:

Атрибут Описание
eventType Указывает тип действия, например, щелчок, редактирование текста и т. д. Требуется для каждого действия.
elementDescriptors Дескрипторы, идентифицирующие виджет пользовательского интерфейса. Требуется для всех действий, имеющих целевой виджет пользовательского интерфейса, например, нажатие определенной кнопки.
optional Если установлено значение true , это действие пропускается, когда его невозможно выполнить. Например, это действие пропускается, когда оно не может найти свой целевой виджет пользовательского интерфейса на экране – без сбоя содержащего его скрипта Robo. По умолчанию значение равно false .
replacementText Текст для ввода в целевой виджет пользовательского интерфейса. Требуется для действий по редактированию текста.
swipeDirection Указывает направление смахивания. Требуется для действий смахивания.
delayTime Указывает, как долго ждать, в миллисекундах. Требуется для действий ожидания.
pointTapXCoordinate и pointTapYCoordinate Координаты пикселей X и Y точки нажатия. Взаимоисключающие с pointTapXPercent и pointTapYPercent . Требуется для действий нажатия точки.
pointTapXPercent и pointTapYPercent Процентные координаты X и Y точки касания. Взаимоисключающие с pointTapXCoordinate и pointTapYCoordinate . Требуется для действий касания точки.

Ниже приведен пример скрипта Robo с двумя действиями без целевых виджетов пользовательского интерфейса. Это означает, что эти действия не работают с определенным виджетом пользовательского интерфейса:

[
  {
    "eventType": "WAIT",
    "delayTime": 3000
  },
  {
    "eventType": "PRESSED_BACK"
  }
]

Описатели элементов

Дескриптор элемента идентифицирует виджет пользовательского интерфейса, используя один или несколько из следующих идентификационных атрибутов:

Атрибут Описание
className
ancestorClassName Имя класса предка иерархии пользовательского интерфейса элемента. Предком является любой из родительских узлов в иерархии пользовательского интерфейса элемента, включая сам элемент.
resourceId
resourceIdRegex Регулярное выражение Java для сопоставления resourceId .
contentDescription
contentDescriptionRegex Регулярное выражение Java для сопоставления contentDescription .
text (который появляется на экране)
textRegex Регулярное выражение Java для сопоставления text .
groupViewChildPosition , recyclerViewChildPosition или adapterViewChildPosition Представляет дочернюю позицию виджета пользовательского интерфейса в зависимости от типа его родительского виджета.

Часто эти атрибуты не определены, например, кнопка может не иметь текста и описания содержимого. Даже если некоторые значения атрибутов присутствуют, они могут не быть уникальными на данном экране приложения (включая resourceId ).

Например, различение элементов списка обычно возможно только с помощью их различных дочерних позиций в родительском виджете. Это означает, что использование только одного дескриптора элемента для идентификации виджета пользовательского интерфейса обычно недостаточно. Поэтому атрибут elementDescriptors действия содержит последовательность дескрипторов элементов, которые упорядочены таким образом, что первый соответствует целевому виджету пользовательского интерфейса, второй соответствует родительскому виджету целевого виджета пользовательского интерфейса и т. д. Целевой виджет пользовательского интерфейса действия считается сопоставленным, когда все его дескрипторы элементов соответствуют соответствующей подиерархии виджетов пользовательского интерфейса.

Ниже приведен пример скрипта Robo с действиями по изменению текста и щелчку, оба из которых требуют от вас определения целевого виджета пользовательского интерфейса с помощью предоставленных дескрипторов элементов:

[
  {
    "eventType": "VIEW_TEXT_CHANGED",
    "replacementText": "John",
    "elementDescriptors": [
      {
        "className": "android.support.v7.widget.AppCompatEditText",
        "groupViewChildPosition": 0,
        "resourceId": "com.google.samples.apps.topeka:id/first_name"
      },
      {
        "className": "android.widget.FrameLayout",
        "groupViewChildPosition": 0
      },
      {
        "className": "android.support.design.widget.TextInputLayout",
        "groupViewChildPosition": 1
      }
    ]
  },
  {
    "eventType": "VIEW_CLICKED",
    "elementDescriptors": [
      {
        "className": "android.support.design.widget.FloatingActionButton",
        "groupViewChildPosition": 1,
        "resourceId": "com.google.samples.apps.topeka:id/done"
      },
      {
        "className": "android.widget.FrameLayout",
        "groupViewChildPosition": 1,
        "resourceId": "com.google.samples.apps.topeka:id/content"
      },
      {
        "className": "android.widget.FrameLayout",
        "groupViewChildPosition": 0,
        "resourceId": "com.google.samples.apps.topeka:id/sign_in_content"
      }
    ]
  }
]

Варианты исполнения

Вы можете опционально префиксировать список действий в скрипте Robo с помощью объекта JSON, который определяет параметры выполнения для этого скрипта Robo. Этот заголовок конфигурации начинается с ключевого слова roboscript , за которым следует представление JSON желаемых параметров выполнения.

Скрипты Robo поддерживают следующие варианты выполнения:

  • executionMode — параметры выполнения, применяемые при запуске скрипта Robo:
    • strict - если установлено значение true , скрипт Robo не использует частичное соответствие, пропуск текущего действия и приостановку . То есть скрипт Robo выполняется как обычный инструментальный тест и завершается неудачей, как только любое из его действий не может быть выполнено. По умолчанию установлено значение false .
    • dismiss_popups — если установлено значение true , Robo test отклоняет любые неожиданные диалоги при выполнении скрипта Robo даже в strict режиме. Эта опция не действует, если режим не strict . По умолчанию она равна false .
    • notify - если установлено значение false , скрипт Robo не показывает уведомления на экране в начале и конце своего выполнения. По умолчанию установлено true .
  • postscript - параметры выполнения, применяемые после завершения скрипта Robo:
    • terminate - если установлено значение true , Robo test останавливает сканирование после завершения скрипта Robo. По умолчанию установлено значение false .

Ниже приведен пример скрипта Robo, выполняемого в strict режиме без экранных уведомлений, который ждет три секунды, после чего сканирование останавливается:

"roboscript": {
  "executionMode": {
    "strict": true,
    "notify": false
  },
  "postscript": {
    "terminate": true
  }
}
[
  {
    "eventType": "WAIT",
    "delayTime": 3000
  }
]

Параметры шаблона

Параметр шаблона — это заполнитель в скрипте Robo, который заменяется фактическим значением, когда тест Robo загружает этот скрипт Robo для выполнения. Параметры шаблона имеют префикс в виде двойного подчеркивания, за которым следует знак процента, и постфикс в виде знака процента, за которым следует двойной подчеркивание.

Скрипты Robo поддерживают следующий параметр шаблона:

  • __%APP_PACKAGE_NAME%__ - имя пакета тестируемого приложения.

Ниже приведен пример скрипта Robo, который останавливает процесс тестирования приложения:

[
  {
    "eventType": "ADB_SHELL_COMMAND",
    "command": "am force-stop __%APP_PACKAGE_NAME%__"
  }
]

Комментарии

Скрипт Robo может содержать строки комментариев, которые начинаются с # или // .

Ниже приведен пример скрипта Robo с несколькими комментариями:

# Confirm a user account.
[
  {
    // Click the DONE button.
    "eventType": "VIEW_CLICKED",
    "elementDescriptors": [
      {
        "resourceId": "com.google.samples.apps.topeka:id/done"
      }
    ]
  }
]

Возможности

По умолчанию, пока все действия скрипта Robo не будут завершены (или, по крайней мере, предприняты попытки), скрипт Robo остается активным. Тест Robo продолжает пытаться сопоставить действие скрипта Robo всякий раз, когда он выбирает действие для выполнения. Скрипт Robo использует следующие методы для повышения надежности:

Техника Описание
Частичное совпадение Если текущее действие скрипта Robo не может быть полностью сопоставлено, критерии сопоставления ослабляются, и сопоставление повторяется. Частичное сопоставление не учитывает дескриптор самого внешнего элемента при сопоставлении целевого виджета пользовательского интерфейса действия скрипта Robo.

Если частичное соответствие успешно, соответствующее действие скрипта Robo выполняется как обычно. Эта техника поддерживает сценарии, в которых структура приложения меняется, например, между версиями приложения, когда элементы экрана перестраиваются.

Пропустить текущее действие Если текущее действие скрипта Robo не может быть полностью или частично сопоставлено, Robo пытается сопоставить последующее действие скрипта Robo. Если последующее действие полностью или частично совпадает, тест Robo пропускает (и никогда не возвращается) текущее действие скрипта Robo и выполняет последующее.

Этот метод поддерживает сценарии, когда поведение приложения меняется между версиями или работает нестабильно, например, когда прерывистый диалог может появляться на разных экранах во время записи или воспроизведения скрипта Robo.

Приостановить Если ни текущее, ни последующие действия скрипта Robo не могут быть полностью или частично сопоставлены, скрипт Robo временно приостанавливается, и тест Robo выбирает действие для выполнения, используя другие стратегии. После завершения этого действия тест Robo возобновляет выполнение скрипта Robo.

Пока текущие или последующие действия скрипта Robo не могут быть сопоставлены, скрипт Robo остается приостановленным для любого количества действий. Таким образом, скрипты Robo не обязательно должны быть прологом для теста Robo, и вы можете перемежать действия скрипта Robo со стандартными действиями теста Robo. Этот метод поддерживает сценарии, когда поведение приложения нестабильно или когда изменения между версиями приложения достаточно велики, чтобы тест Robo должен был «заполнить пробелы» своими стандартными действиями.

Приоритеты

Если скрипт Robo достигает своего maxNumberOfRuns , он больше не может быть запущен в данном цикле. Если текущий контекст может запустить более одного скрипта Robo, приоритет отдается путем выбора в следующем порядке скрипта Robo, который:

  1. Имеет атрибут contextDescriptor .
  2. Имеет наивысший priority (по умолчанию все скрипты Robo имеют одинаковый priority выполнения 1 ).
  3. Появляется первым в списке скриптов 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 запускает следующие действия в следующем порядке:

  1. "Robo script 2" , поскольку он имеет наивысший приоритет.
  2. "Robo script 1" поскольку он появляется раньше среди оставшихся применимых Robo-скриптов с тем же приоритетом.
  3. "Robo script 3" — последний применимый Robo script.

Повторные прогоны

По умолчанию Robo запускает скрипт Robo не чаще одного раза во время сканирования. Это можно настроить с помощью атрибута maxNumberOfRuns .

Ниже приведен пример скрипта Robo, который переводит тестируемое приложение в фоновый режим до 10 раз:

{
  "id": 1000,
  "maxNumberOfRuns": 10,
  "contextDescriptor": {
    "condition": "app_under_test_shown"
  },
  "actions": [
    {
      "eventType": "GO_HOME"
    }
  ]
}

Стадия ползания

Скрипты Robo применяются на разных этапах конкретного роботизированного сканирования:

Стадия ползания Описание
pre_crawl Прежде чем Robo запустится и начнет сканирование тестируемого приложения.
post_crawl После того, как Robo закончит сканирование тестируемого приложения. Скрипт post_crawl Robo не должен длиться более 15 секунд, иначе сканирование может завершиться из-за тайм-аута.
crawl Основной этап сканирования, когда Robo сканирует тестируемое приложение.
close_screen Когда Robo пытается вернуться назад (backtrack) с заданного экрана, когда все возможные действия на этом экране исследованы. По умолчанию Robo нажимает назад, что нежелательно в некоторых сценариях.

Если атрибут crawlStage скрипта Robo не указан, подразумевается, что он равен crawl .

Ниже приведен пример скрипта Robo, который очищает данные пользователя тестируемого приложения перед тем, как Robo начнет их сканирование:

{
  "id": 1000,
  "crawlStage": "pre_crawl",
  "actions": [
    {
      "eventType": "ADB_SHELL_COMMAND",
      "command": "pm clear __%APP_PACKAGE_NAME%__"
    }
  ]
}

Ниже приведен пример скрипта Robo, который предписывает Robo нажимать кнопку "Cancel" всякий раз, когда он пытается вернуться назад (вернуться) из диалогового окна подтверждения:

{
  "id": 1000,
  "crawlStage": "close_screen",
  "maxNumberOfRuns": 999,
  "contextDescriptor": {
    "condition": "element_present",
    "elementDescriptors": [
      {
        "resourceId": "my.app.package:id/confirmation_dialog"
      }
    ]
  },
  "actions": [
    {
      "eventType": "VIEW_CLICKED",
      "elementDescriptors": [
        {
          "text": "Cancel"
        }
      ]
    }
  ]
}

Условные действия

Скрипт Robo может содержать условные действия. Условные действия имеют три дополнительных атрибута, которые описывают, как Robo их выполняет:

Атрибут Описание
priority Приоритет этого условного действия по сравнению с другими условными действиями в содержащем его скрипте Robo. По умолчанию все условные действия имеют приоритет 1 .
maxNumberOfRuns Сколько раз это условное действие может быть выполнено во время одного выполнения содержащего его скрипта Robo. По умолчанию все условные действия могут быть выполнены не более одного раза за одно выполнение содержащего их скрипта Robo.
contextDescriptor Контекст/условие, которое запускает это условное действие. Имеет ту же структуру и предлагает аналогичные возможности, что и contextDescriptor скрипта Robo

При запуске скрипт Robo выполняет свои безусловные действия одно за другим в порядке появления. Если скрипт Robo содержит условные действия, то они рассматриваются каждый раз перед выбором безусловного действия для выполнения. Если какое-либо условное действие запускается и выбирается на основе его приоритета и оставшегося количества запусков, то скрипт Robo выполняет это условное действие. В противном случае скрипт Robo выполняет следующее безусловное действие. Чтобы быть действительным, скрипт Robo должен содержать по крайней мере одно безусловное действие.

Ниже приведен пример безусловного скрипта Robo с условным действием, которое закрывает всплывающие диалоговые окна, если они появляются в любой момент выполнения скрипта Robo:

{
  "id": 1000,
  "actions": [
    {
      "description": "Dismiss popup",
      "maxNumberOfRuns": 100,
      "contextDescriptor": {
        "condition": "default_launcher_shown",
        "negateCondition": true
      },
      "eventType": "GO_HOME"
    },
    {
      "description": "Screen off",
      "eventType": "ADB_SHELL_COMMAND",
      "command": "input keyevent 26"
    },
    {
      "description": "Wait for 10 seconds",
      "eventType": "WAIT",
      "delayTime": 10000
    },
    {
      "description": "Screen on",
      "eventType": "ADB_SHELL_COMMAND",
      "command": "input keyevent 82"
    },
    {
      "description": "Wait for 10 seconds",
      "eventType": "WAIT",
      "delayTime": 10000
    }
}

Игнорирование действий

Скрипт Robo может содержать инструкции для Robo игнорировать определенные виджеты пользовательского интерфейса или все виджеты пользовательского интерфейса на определенном экране. Эти инструкции представлены как игнорирование "действий" с eventType ELEMENT_IGNORED и ALL_ELEMENTS_IGNORED соответственно.

Всякий раз, когда атрибут contextDescriptor скрипта Robo, содержащего игнорируемые действия, соответствует заданному экрану, Robo не взаимодействует ни с какими виджетами пользовательского интерфейса, на которые нацелены его игнорируемые действия (если только какое-либо другое действие скрипта Robo не заставляет Robo выполнить действие над одним из игнорируемых виджетов пользовательского интерфейса).

Скрипт Robo может содержать смесь игнорирующих, условных и безусловных действий. В отличие от других действий скрипта Robo, игнорирующие действия применяются до тех пор, пока contextDescriptor содержащего их скрипта Robo соответствует экрану во время сканирования Robo, независимо от значений атрибутов priority и maxNumberOfRuns .

Ниже приведен пример файла с двумя скриптами Robo. Первый скрипт Robo заставляет Robo игнорировать все виджеты пользовательского интерфейса на экране, содержащем виджет пользовательского интерфейса с идентификатором ресурса "my.app.package:id/ignored_screen" . Второй скрипт Robo заставляет Robo игнорировать виджеты пользовательского интерфейса, идентификаторы ресурсов которых соответствуют регулярному выражению Java ".*:id/done" на экране, содержащем виджет пользовательского интерфейса с идентификатором ресурса "my.app.package:id/main_screen" :

[
  {
    "id": 1000,
    "contextDescriptor": {
      "condition": "element_present",
      "elementDescriptors": [
        {
          "resourceId": "my.app.package:id/ignored_screen"
        }
      ]
    },
    "actions": [
      {
        "eventType": "ALL_ELEMENTS_IGNORED"
      }
    ]
  },
  {
    "id": 1001,
    "contextDescriptor": {
      "condition": "element_present",
      "elementDescriptors": [
        {
          "resourceId": "my.app.package:id/main_screen"
        }
      ]
    },
    "actions": [
      {
        "eventType": "ELEMENT_IGNORED",
        "elementDescriptors": [
          {
            "resourceIdRegex": ".*:id/done"
          }
        ]
      }
    ]
  }
]

Поддержка RecyclerView и AdapterView

Дочерние элементы виджетов RecyclerView и AdapterView загружаются динамически и могут отображаться на расстоянии многих смахиваний от текущего экрана. Поскольку размер экрана и количество смахиваний, необходимых для перехода к дочернему элементу, различаются для разных форм-факторов устройств, гораздо надежнее полагаться на позицию данных дочернего элемента, которая является абсолютной. Менее надежный подход — полагаться на количество смахиваний, необходимых для вывода дочернего элемента на экран, а затем использовать его позицию на экране.

Таким образом, скрипт Robo захватывает абсолютные позиции данных дочерних элементов RecyclerView, которые являются целями действий скрипта Robo, как recyclerViewChildPosition . Скрипт Robo также захватывает абсолютные позиции данных дочерних элементов AdapterView, которые являются целями действий скрипта Robo, как adapterViewChildPosition .

Действия над дочерними элементами RecyclerView и AdapterView выполняются в следующей последовательности:

  1. Тест Robo обеспечивает отображение соответствующего дочернего элемента на экране посредством действия позиционирования на содержащем его RecyclerView или AdapterView.

  2. Robo-тест выполняет записанное действие непосредственно над дочерним элементом, поскольку оно уже отображается на экране.

Ниже приведен пример действия щелчка на дочернем элементе AdapterView ( android.widget.GridView ):

{
  "eventType": "VIEW_CLICKED",
  "elementDescriptors": [
    {
      "className": "com.google.samples.apps.topeka.widget.AvatarView",
      "adapterViewChildPosition": 5,
      "resourceId": "com.google.samples.apps.topeka:id/avatar",
      "contentDescription": "Avatar 6"
    },
    {
      "className": "android.widget.GridView",
      "groupViewChildPosition": 1,
      "resourceId": "com.google.samples.apps.topeka:id/avatars"
    },
    {
      "className": "android.widget.LinearLayout",
      "groupViewChildPosition": 1
    },
    {
      "className": "android.widget.LinearLayout",
      "groupViewChildPosition": 0
    }
  ]
}

Ниже приведен пример действия щелчка на дочернем элементе RecyclerView ( android.support.v7.widget.RecyclerView ):

{
  "eventType": "VIEW_CLICKED",
  "elementDescriptors": [
    {
      "className": "android.support.v7.widget.AppCompatTextView",
      "groupViewChildPosition": 1,
      "resourceId": "com.google.samples.apps.topeka:id/category_title"
    },
    {
      "className": "android.widget.FrameLayout",
      "recyclerViewChildPosition": 8,
      "resourceId": "com.google.samples.apps.topeka:id/category_item"
    },
    {
      "className": "android.support.v7.widget.RecyclerView",
      "groupViewChildPosition": 1,
      "resourceId": "com.google.samples.apps.topeka:id/categories"
    },
    {
      "className": "android.widget.FrameLayout",
      "groupViewChildPosition": 1,
      "resourceId": "com.google.samples.apps.topeka:id/category_container"
    },
    {
      "className": "android.widget.LinearLayout",
      "groupViewChildPosition": 0
    }
  ]
}

Запишите скрипт Robo в Android Studio и запустите его в Test Lab

Вы можете создать скрипт Robo в Android Studio, который сохранит скрипт как файл JSON. Затем вы можете загрузить файл JSON в Firebase Test Lab вместе с приложением и запустить тест соответствующим образом.

При запуске Robo-теста с прикрепленным сценарием Robo-тест сначала выполняет заранее заданные действия, а затем исследует приложение как обычно.

Чтобы создать JSON-файл скрипта Robo в Android Studio, следуйте инструкциям в разделе Запись скрипта Robo с помощью Test Lab в Android Studio .

Действия скрипта Robo

Следующий общий необязательный атрибут применяется ко всем действиям:

  • description - помогает отслеживать выполнение этого действия скрипта Robo в выходных данных теста Robo.

Утверждение

Если утверждаемое условие истинно, скрипт Robo переходит к следующему действию, которое может быть другим утверждением. В противном случае выполнение скрипта Robo останавливается из-за невыполненного утверждения.

В следующей таблице перечислены требуемые атрибуты:

Атрибут Описание
"eventType": "ASSERTION" --
contextDescriptor Описывает утверждаемый контекст или условие. Имеет ту же структуру и предлагает аналогичные возможности, что и contextDescriptor скрипта Robo .

Ниже приведен пример утверждения скрипта Robo, который проверяет, находится ли тестируемое приложение на переднем плане:

{
  "eventType": "ASSERTION",
  "contextDescriptor": {
    "condition": "app_under_test_shown"
  }
}

Ниже приведен пример утверждения скрипта Robo, который проверяет наличие на экране виджета пользовательского интерфейса с идентификатором ресурса "com.google.samples.apps.topeka:id/done" :

{
  "eventType": "ASSERTION",
  "contextDescriptor": {
    "condition": "element_present",
    "elementDescriptors": [
      {
        "resourceId": "com.google.samples.apps.topeka:id/done"
      }
    ]
  }
}

Ниже приведен пример утверждения скрипта Robo, который проверяет, что "Settings" НЕ обнаружены на экране с помощью OCR:

{
  "eventType": "ASSERTION",
  "contextDescriptor": {
    "condition": "element_present",
    "negateCondition": true,
    "visionText": "Settings"
  }
}

Нажмите

В следующей таблице перечислены требуемые атрибуты:

Атрибут Описание
eventType Указывает тип действия скрипта Robo.
"eventType": "VIEW_CLICKED" Нажимает на целевой элемент тестируемого приложения.
"eventType": "SOFT_KEYBOARD_CLICK" Кликает по целевому элементу экранной клавиатуры.
"eventType": "SOFT_KEYBOARD_RANDOM_CLICK" Кликает по случайным элементам экранной клавиатуры до maxNumberOfRuns раз.
"eventType": "LIST_ITEM_CLICKED" Используется средством записи скриптов Robo в Android Studio для нажатия на элементы списка.
elementDescriptors Определяет выбранный виджет пользовательского интерфейса с помощью иерархии пользовательского интерфейса Android. Взаимоисключающее с visionText .
visionText Идентифицирует выбранный элемент с помощью OCR. Взаимоисключающее с elementDescriptors .
matchIndex Указывает индекс вхождения совпавшего целевого элемента, когда целевой элемент идентифицируется с помощью visionText . Если он равен 0 , действие скрипта Robo выбирает первый совпавший элемент, если он равен 1 , действие скрипта Robo выбирает второй совпавший элемент и т. д. Порядок определяется слева направо, сверху вниз. Значение по умолчанию равно 0 (выбирается первое совпадение).
maxNumberOfRuns Указывает, сколько раз следует щелкнуть случайный элемент программной клавиатуры, когда eventTypeSOFT_KEYBOARD_RANDOM_CLICK . Значение по умолчанию — 1 .

Ниже приведен пример действия скрипта Robo, который нажимает кнопку с идентификатором ресурса "com.google.samples.apps.topeka:id/done" :

{
  "eventType": "VIEW_CLICKED",
  "elementDescriptors": [
    {
      "resourceId": "com.google.samples.apps.topeka:id/done"
    }
  ]
}

Ниже приведен пример действия скрипта Robo, который нажимает на второе вхождение слова "Search" обнаруженное на экране с помощью OCR:

{
  "eventType": "VIEW_CLICKED",
  "visionText": "Search",
  "matchIndex": 1
}

Ниже приведен пример действия скрипта Robo, который нажимает на элемент экранной клавиатуры с описанием содержимого "Emoji button" :

{
  "eventType": "SOFT_KEYBOARD_CLICK",
  "elementDescriptors": [
    {
      "contentDescription": "Emoji button"
    }
  ]
}

Ниже приведен пример действия скрипта Robo, который нажимает случайные элементы экранной клавиатуры до пяти раз:

{
  "eventType": "SOFT_KEYBOARD_RANDOM_CLICK",
  "maxNumberOfRuns": 5
}

Отключить программную клавиатуру

В следующей таблице перечислены требуемые атрибуты:

Атрибут Описание
"eventType": "DISABLE_KEYBOARD" --

Ниже приведен пример действия скрипта Robo, отключающего программную клавиатуру:

{
  "eventType": "DISABLE_KEYBOARD"
}

Выполнить команду оболочки adb

В следующей таблице перечислены требуемые атрибуты:

Атрибут Описание
"eventType": "ADB_SHELL_COMMAND" --
command Команда оболочки Android Debug Bridge (adb), которую необходимо выполнить.

Следующий атрибут является необязательным:

  • expectedOutputRegex — ожидаемый вывод команды в виде регулярного выражения Java. Если вывод не совпадает, действие скрипта Robo завершается неудачей. По умолчанию это пустая строка, что означает, что вывод не проверяется.

Ниже приведен пример действия скрипта Robo, который очищает данные пользователя тестируемого приложения:

{
  "eventType": "ADB_SHELL_COMMAND",
  "command": "pm clear __%APP_PACKAGE_NAME%__"
}

Предоставить разрешения

Это действие записывается Robo script recorder в Android Studio для обратной совместимости с Espresso Test Recorder . Robo test предоставляет все разрешения тестируемому приложению в начале каждого сканирования, и, таким образом, это действие является пустым. НЕ используйте это действие в своих Robo scripts.

В следующей таблице перечислены требуемые атрибуты:

Атрибут Описание
"eventType": "PERMISSIONS_REQUEST" --

Игнорировать все элементы на экране

Это действие заставляет Robo игнорировать все элементы на любом экране, который запускает содержащий его скрипт Robo.

В следующей таблице перечислены требуемые атрибуты:

Атрибут Описание
"eventType": "ALL_ELEMENTS_IGNORED" --

Ниже приведен пример действия скрипта Robo, который заставляет Robo игнорировать все элементы на экране:

{
  "eventType": "ALL_ELEMENTS_IGNORED"
}

Игнорировать элемент

Это действие заставляет Robo игнорировать элемент (или элементы), соответствующие указанным elementDescriptors .

В следующей таблице перечислены требуемые атрибуты:

Атрибут Описание
"eventType": "ELEMENT_IGNORED" --
elementDescriptors Идентифицирует игнорируемые виджеты пользовательского интерфейса с помощью иерархии пользовательского интерфейса Android.

Следующий атрибут является необязательным:

  • ignoreChildren - если установлено значение true , Robo также игнорирует всех потомков игнорируемых виджетов пользовательского интерфейса. По умолчанию установлено значение false .

Ниже приведен пример действия скрипта Robo, который заставляет Robo игнорировать все элементы, описания содержимого которых начинаются с "Avatar" :

{
  "eventType": "ELEMENT_IGNORED",
  "elementDescriptors": [
    {
      "contentDescriptionRegex": "Avatar.*"
    }
  ]
}

Введите текст

В следующей таблице перечислены требуемые атрибуты:

Атрибут Описание
eventType Указывает тип действия скрипта Robo.
"eventType": "VIEW_TEXT_CHANGED" Вводит указанный текст в целевой виджет пользовательского интерфейса.
"eventType": "ENTER_TEXT" вводит заданный текст в целевой виджет пользовательского интерфейса, а затем отправляет событие KEYCODE_ENTER этому виджету пользовательского интерфейса.
elementDescriptors Определяет целевой виджет пользовательского интерфейса с помощью иерархии пользовательского интерфейса Android.
replacementText Текст для ввода в целевой виджет пользовательского интерфейса.

Ниже приведен пример действия скрипта Robo, который вводит "John" в виджет пользовательского интерфейса с идентификатором ресурса "com.google.samples.apps.topeka:id/first_name" :

{
  "eventType": "VIEW_TEXT_CHANGED",
  "replacementText": "John",
  "elementDescriptors": [
    {
      "resourceId": "com.google.samples.apps.topeka:id/first_name"
    }
  ]
}

Длительный щелчок

В следующей таблице перечислены требуемые атрибуты:

Атрибут Описание
"eventType": "VIEW_LONG_CLICKED" --
elementDescriptors Определяет целевой виджет пользовательского интерфейса с использованием иерархии пользовательского интерфейса Android. Взаимоисключающее с visionText .
visionText Определяет элемент, на котором долго нажимали, с помощью OCR. Взаимоисключающее с elementDescriptors .
matchIndex Указывает индекс вхождения совпавшего целевого элемента, когда целевой элемент идентифицируется с помощью visionText . Если он равен 0 , действие скрипта Robo выбирает первый совпавший элемент, если он равен 1 , действие скрипта Robo выбирает второй совпавший элемент и т. д. Порядок определяется слева направо, сверху вниз. Значение по умолчанию равно 0 (выбирается первое совпадение).

Следующий атрибут является необязательным:

  • delayTime — указывает, как долго длится нажатие при длинном щелчке, в миллисекундах.

Ниже приведен пример действия скрипта Robo, который выполняет пятисекундный щелчок по виджету пользовательского интерфейса с описанием содержимого "Avatar 8" :

{
  "eventType": "VIEW_LONG_CLICKED",
  "elementDescriptors": [
    {
      "contentDescription": "Avatar 8"
    }
  ],
  "delayTime": 5000
}

Выполнить одноточечный жест

В следующей таблице перечислены требуемые атрибуты:

Атрибут Описание
"eventType": "ONE_POINT_GESTURE" --
coordinates Две координаты для одноточечного жеста, отформатированные как «(x1,y1)->(x2,y2)» в процентах или пикселях.

Следующий атрибут является необязательным:

  • dragAndDrop — если установлено значение true , одноточечный жест выполняет действие перетаскивания. По умолчанию установлено значение false .

Ниже приведен пример одноточечного жестового действия скрипта Robo, которое выполняет смахивание вниз:

{
  "eventType": "ONE_POINT_GESTURE",
  "coordinates": "(50%,25%)->(50%,75%)"
}

Выполнить двухточечный жест

В следующей таблице перечислены требуемые атрибуты:

Атрибут Описание
"eventType": "TWO_POINT_GESTURE" --
coordinates Четыре координаты для двухточечного жеста, отформатированные как «(x1,y1)->(x2,y2),(x3,y3)->(x4,y4)» в процентах или пикселях.

Ниже приведен пример действия скрипта Robo, выполняющего жест разведения пальцев:

{
  "eventType": "TWO_POINT_GESTURE",
  "coordinates": "(50%,50%)->(25%,50%),(50%,50%)->(75%,50%)"
}

Выполнить действие IME

Это действие нажимает кнопку текущего действия, например, «Далее», «Готово» и «Поиск», в редакторе методов ввода (IME) для указанного целевого виджета пользовательского интерфейса.

В следующей таблице перечислены требуемые атрибуты:

Атрибут Описание
"eventType": "PRESSED_EDITOR_ACTION" --
elementDescriptors Определяет целевой виджет пользовательского интерфейса с помощью иерархии пользовательского интерфейса Android.

Ниже приведен пример действия скрипта Robo, который выполняет действие IME для виджета пользовательского интерфейса с идентификатором ресурса "com.google.samples.apps.topeka:id/first_name" :

{
  "eventType": "PRESSED_EDITOR_ACTION",
  "elementDescriptors": [
    {
      "resourceId": "com.google.samples.apps.topeka:id/first_name"
    }
  ]
}

Нажмите назад

В следующей таблице перечислены требуемые атрибуты:

Атрибут Описание
eventType Указывает тип действия скрипта Robo.
"eventType": "PRESSED_BACK" Отправляет на устройство событие KEYCODE_BACK .
"eventType": "PRESSED_BACK_EMULATOR_28" Используется средством записи скриптов Robo в Android Studio для обратного нажатия на эмуляторы API 28.

Ниже приведен пример действия скрипта Robo, который нажимает «назад»:

{
  "eventType": "PRESSED_BACK"
}

Пресс-центр

Это действие отправляет на устройство событие KEYCODE_HOME .

В следующей таблице перечислены требуемые атрибуты:

Атрибут Описание
"eventType": "GO_HOME" --

Ниже приведен пример действия скрипта Robo, которое приводит к щелчку:

{
  "eventType": "GO_HOME"
}

Прокрутите элемент в поле зрения

Это действие заставляет Robo test прокручивать вперед виджет пользовательского интерфейса, соответствующий указанным elementDescriptors , до тех пор, пока на экране не появится виджет пользовательского интерфейса, соответствующий указанным childElementDescriptors , или пока прокручиваемый виджет больше не сможет прокручиваться, или пока не будет достигнуто максимальное количество прокруток в 50.

В следующей таблице перечислены требуемые атрибуты:

Атрибут Описание
"eventType": "ELEMENT_SCROLL_INTO_VIEW" --
elementDescriptors Определяет прокручиваемый виджет пользовательского интерфейса с помощью иерархии пользовательского интерфейса Android.
childElementDescriptors Определяет виджет пользовательского интерфейса для прокрутки с использованием иерархии пользовательского интерфейса Android.

Ниже приведен пример действия скрипта Robo, который прокручивает виджет пользовательского интерфейса с идентификатором ресурса "my.app.package:id/scrollable_card_container" до тех пор, пока на экране не появится виджет пользовательского интерфейса с текстом "Orange" (или пока не станет возможным выполнить больше прокруток, или пока не будет достигнуто максимальное количество прокруток в 50):

{
  "eventType": "ELEMENT_SCROLL_INTO_VIEW",
  "elementDescriptors": [
    {
      "resourceId": "my.app.package:id/scrollable_card_container"
    }
  ],
  "childElementDescriptors": [
    {
      "text": "Orange"
    }
  ]
}

Проведите пальцем

В следующей таблице перечислены требуемые атрибуты:

Атрибут Описание
"eventType": "VIEW_SWIPED" --
swipeDirection Задает направление смахивания:
  • Left
  • Right
  • Up
  • Down
  • ForwardDown или Right в зависимости от вертикальной или горизонтальной прокрутки целевого виджета пользовательского интерфейса.
  • BackwardUp или Left в зависимости от вертикальной или горизонтальной прокрутки целевого виджета пользовательского интерфейса.
elementDescriptors Определяет целевой виджет пользовательского интерфейса с помощью иерархии пользовательского интерфейса Android.

Ниже приведен пример действия скрипта Robo, который смахивает виджет пользовательского интерфейса с идентификатором ресурса "my.app.package:id/custom_content" :

{
  "eventType": "VIEW_SWIPED",
  "swipeDirection": "Up",
  "elementDescriptors": [
    {
      "resourceId": "my.app.package:id/custom_content"
    }
  ]
}

Сделать снимок экрана

В следующей таблице перечислены требуемые атрибуты:

Атрибут Описание
"eventType": "TAKE_SCREENSHOT" --
screenshotName Указывает имя файла снимка экрана.

Ниже приведен пример действия скрипта Robo, который делает снимок экрана:

{
  "eventType": "TAKE_SCREENSHOT",
  "screenshotName": "my_screenshot"
}

Нажмите на точку на экране

В следующей таблице перечислены требуемые атрибуты:

Атрибут Описание
"eventType": "POINT_TAP" --
pointTapXCoordinate Координата X пикселя точки нажатия. Взаимоисключающее с pointTapXPercent и pointTapYPercent .
pointTapYCoordinate Координата Y пикселя точки нажатия. Взаимоисключающее с pointTapXPercent и pointTapYPercent .
pointTapXPercent Процентная координата X точки касания. Взаимоисключающая с pointTapXCoordinate и pointTapYCoordinate .
pointTapYPercent Процентная координата Y точки касания. Взаимоисключающая с pointTapXCoordinate и pointTapYCoordinate .

Ниже приведен пример действия скрипта Robo, который нажимает на середину экрана:

{
  "eventType": "POINT_TAP",
  "pointTapXPercent": 50,
  "pointTapYPercent": 50
}

Нажмите на точку внутри элемента

В следующей таблице перечислены требуемые атрибуты:

Атрибут Описание
"eventType": "POINT_TAP_ELEMENT" --
pointTapXPercent Процентная координата X внутри целевого элемента.
pointTapYPercent Процентная координата Y внутри целевого элемента.
elementDescriptors Определяет целевой виджет пользовательского интерфейса с использованием иерархии пользовательского интерфейса Android.

Ниже приведен пример действия скрипта Robo, который перемещает ползунок полосы поиска вправо:

{
  "eventType": "POINT_TAP_ELEMENT",
  "pointTapXPercent": 80,
  "pointTapYPercent": 50,
  "elementDescriptors": [
    {
      "resourceId": "my.app.package:id/my_seekbar"
    }
  ]
}

Прекратить сканирование

Это действие останавливает Robo-тест.

В следующей таблице перечислены требуемые атрибуты:

Атрибут Описание
"eventType": "TERMINATE_CRAWL" --

Ниже приведен пример действия скрипта Robo, останавливающего тест Robo:

{
  "eventType": "TERMINATE_CRAWL"
}

Ждать

В следующей таблице перечислены требуемые атрибуты:

Атрибут Описание
"eventType": "WAIT" (or "DELAYED_MESSAGE_POSTED") --
delayTime Указывает время ожидания в миллисекундах.

Ниже приведен пример действия скрипта Robo, который ждет три секунды:

{
  "eventType": "WAIT",
  "delayTime": 3000
}

Подождите элемент

Это действие заставляет Robo test ждать появления элемента на экране в течение указанного времени ожидания.

В следующей таблице перечислены требуемые атрибуты:

Атрибут Описание
"eventType": "WAIT_FOR_ELEMENT" --
delayTime Указывает время ожидания в миллисекундах.
elementDescriptors Идентифицирует ожидаемый виджет пользовательского интерфейса с помощью иерархии пользовательского интерфейса Android.

Ниже приведен пример действия скрипта Robo, который ожидает до 30 секунд, пока на экране появится виджет пользовательского интерфейса с идентификатором ресурса "my.app.package:id/confirmation_button" :

{
  "eventType": "WAIT_FOR_ELEMENT",
  "delayTime": 30000,
  "elementDescriptors": [
    {
      "resourceId": "my.app.package:id/confirmation_button"
    }
  ]
}

Следующие шаги