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

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

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

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

  • Создайте сценарий Робо вручную. (Android и iOS+)

  • Запишите сценарий Робо, а затем отредактируйте его вручную. (только для 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+ (бета-версия) имеет ограниченную поддержку сценариев Robo. Синтаксис сценария Robo для iOS+ идентичен синтаксису Android, а поддерживаемые функции iOS+ ведут себя аналогично своим аналогам в Android.

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

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

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

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

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

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

Структура

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

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

Один файл содержит набор из одного или нескольких сценариев 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 Количество последовательных действий, не связанных с робо-скриптом, выполненных ранее. Он используется в сочетании с условием non_roboscript_action_performed для запуска сценария Robo после каждого действия робота, nonRoboscriptActionCount . По умолчанию это 1 .

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

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

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

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

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

{
  "contextDescriptor": {
    "condition": "non_roboscript_action_performed"
  },
  "maxNumberOfRuns" : 1000,
  "actions" : [
    {
      "eventType" : "DELAYED_MESSAGE_POSTED",
      "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": "DELAYED_MESSAGE_POSTED",
    "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-представление желаемых параметров выполнения.

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

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

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

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

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

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

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

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

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

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

Комментарии

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

Ниже приведен пример сценария 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 достигает своего maxNumberOfRuns , его больше нельзя будет запустить при данном сканировании. Если в текущем контексте может быть запущено более одного сценария Робо, приоритет отдается путем выбора в следующем порядке сценария Робо, который:

  1. Имеет атрибут contextDescriptor .
  2. Имеет наивысший priority (по умолчанию все сценарии Robo имеют одинаковый priority выполнения — 1 ).
  3. Появляется самым ранним в списке роботизированных сценариев, если приоритеты роботизированных сценариев совпадают.

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

[
  {
    "id": 1000,
    "description": "Robo script 1",
    "contextDescriptor": {
      "condition": "app_under_test_shown"
    },
    "actions": [
      {
        "eventType": "DELAYED_MESSAGE_POSTED",
        "delayTime": 3000
      }
    ]
  },
  {
    "id": 1001,
    "description": "Robo script 2",
    "priority": "2",
    "contextDescriptor": {
      "condition": "app_under_test_shown"
    },
    "actions": [
      {
        "eventType": "DELAYED_MESSAGE_POSTED",
        "delayTime": 3000
      }
    ]
  },
  {
    "id": 1002,
    "description": "Robo script 3",
    "contextDescriptor": {
      "condition": "app_under_test_shown"
    },
    "actions": [
      {
        "eventType": "DELAYED_MESSAGE_POSTED",
        "delayTime": 3000
      }
    ]
  }
]

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

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

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

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

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

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

Этап сканирования

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

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

Если атрибут 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"
        }
      ]
    }
  ]
}

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

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

Атрибут Описание
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": "DELAYED_MESSAGE_POSTED",
      "delayTime": 10000
    },
    {
      "description": "Screen on",
      "eventType": "ADB_SHELL_COMMAND",
      "command": "input keyevent 82"
    },
    {
      "description": "Wait for 10 seconds",
      "eventType": "DELAYED_MESSAGE_POSTED",
      "delayTime": 10000
    }
}

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

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

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

Робо-скрипт может содержать смесь игнорирующих, условных и безусловных действий. В отличие от других действий сценария Robo, действия игнорирования применяются до тех пор, пока содержащий их contextDescriptor сценария 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 и AdaptorView загружаются динамически и могут отображаться при большом удалении от текущего экрана. Поскольку размер экрана и количество пролистываний, необходимых для доступа к этому дочернему элементу, различны для разных форм-факторов устройств, гораздо надежнее полагаться на положение данных дочернего элемента, которое является абсолютным. Менее надежный подход — полагаться на количество пролистываний, необходимых для того, чтобы вывести этого дочернего элемента на экран, а затем использовать его положение на экране.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • description — помогает отслеживать выполнение этого действия сценария робота в результатах теста робота.

Утверждение

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

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

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

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

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

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

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

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

{
  "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" Используется программой записи сценариев Robo в Android Studio для щелчка по элементам списка.
elementDescriptors Идентифицирует выбранный виджет пользовательского интерфейса, используя иерархию пользовательского интерфейса Android. Взаимоисключается с visionText .
visionText Идентифицирует выбранный элемент с помощью OCR. Взаимоисключающий элемент с elementDescriptors .
matchIndex Указывает индекс появления соответствующего целевого элемента, когда целевой элемент идентифицирован с помощью visionText . Если значение равно 0 , действие сценария Робо-скрипта выбирает первый совпадающий элемент, если оно равно 1 , действие сценария Робо-скрипта выбирает второй совпавший элемент и т. д. Порядок определяется слева направо, сверху вниз. Значение по умолчанию — 0 (выбирается первое совпадение).
maxNumberOfRuns Указывает, сколько раз следует щелкнуть случайный элемент виртуальной клавиатуры, если eventType имеет значение SOFT_KEYBOARD_RANDOM_CLICK . Значение по умолчанию — 1 .

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

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

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

{
  "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. Если выходные данные не совпадают, действие сценария Робо не будет выполнено. По умолчанию это пустая строка, что означает, что вывод не проверяется.

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

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

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

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

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

Атрибут Описание
"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 Указывает тип действия сценария Робо.
"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 Идентифицирует элемент, на который щелкнули при длительном нажатии, с помощью OCR. Взаимоисключающий элемент с elementDescriptors .
matchIndex Указывает индекс появления соответствующего целевого элемента, когда целевой элемент идентифицирован с помощью visionText . Если значение равно 0 , действие сценария Робо-скрипта выбирает первый совпадающий элемент, если оно равно 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.

Ниже приведен пример действия сценария 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 Указывает тип действия сценария Робо.
"eventType": "PRESSED_BACK" Отправляет на устройство событие KEYCODE_BACK .
"eventType": "PRESSED_BACK_EMULATOR_28" Используется устройством записи сценариев Robo в Android Studio для обратного вызова API 28 эмуляторов.

Ниже приведен пример действия сценария Робо, которое нажимает назад:

{
  "eventType": "PRESSED_BACK"
}

Нажмите домой

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

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

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

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

{
  "eventType": "GO_HOME"
}

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

Это действие заставляет тест Robo прокручивать вперед виджет пользовательского интерфейса, соответствующий указанным 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 Указывает направление смахивания:
  • Left
  • Right
  • Up
  • Down
  • ForwardDown или Right в зависимости от вертикальной или горизонтальной прокрутки целевого виджета пользовательского интерфейса.
  • BackwardUp или Left в зависимости от вертикальной или горизонтальной прокрутки целевого виджета пользовательского интерфейса.
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" --

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

{
  "eventType": "TERMINATE_CRAWL"
}

Ждать

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

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

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

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

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

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

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

Атрибут Описание
"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"
    }
  ]
}

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