Использование Java SDK для эффективной интеграции AWS Device Farm в конвейер CI.

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

В этой статье мы расскажем, как использовать общедоступное облако AWS Device Farm таким образом, чтобы его можно было легко интегрировать в конвейер CI. В этом примере мы используем Java, Cucumber и Appium, но эти концепции применимы и к другим технологиям.

Модель исполнения на стороне сервера

При выполнении тестов AWS (по крайней мере, в своем общедоступном облаке) использует подход, который я называю выполнением на стороне сервера. Это означает, что тестовый код полностью работает в их инфраструктуре. Альтернативой этому является то, что используют поставщики, такие как Browserstack или Saucelabs, когда тестовый код выполняется на компьютере пользователя, это называется выполнением на стороне клиента и взаимодействует с облачной службой через веб-службу. В общем, выполнение на стороне клиента проще реализовать; Если вы уже знаете, как выполнять тесты локально, вам необходимо внести минимальные изменения в конфигурацию.

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

Выполнение тестов через веб-консоль

Самый простой способ запустить тесты на AWS Device Farm - через веб-консоль. Это утомительный процесс, если вам нужно делать это часто (мы поговорим об использовании их API всего через несколько минут), но просмотр веб-консоли - отличный способ ознакомиться с различными этапами процесса.

Сначала войдем в AWS и откроем панель управления Device Farm:

Затем создаем новый проект:

И создадим наш первый прогон:

Поскольку мы тестируем собственное приложение для Android (StackOverflow), наш первый шаг - загрузить его APK-файл:

Далее нам нужно выбрать тип теста. Мы используем Appium Java JUnit:

Используя Maven, мы можем создать тестовый пакет в виде zip-файла, выполнив действия, описанные в документации. Пусть вас не смущает утверждение, что поддерживается только Java 8. Мы разберемся с этим позже (и, конечно же, вместо этого будем использовать Java 12).

В этой демонстрации мы используем JustTestLah! тестовая среда с использованием Java, Cucumber и Appium (отказ от ответственности: я автор 😉).

Вы можете загрузить тестовый пакет по этой ссылке или собрать демо самостоятельно с помощью Maven (zip-файл будет сгенерирован в justtestlah-demos/target):

После загрузки zip-архива в AWS вас спросят, использовать ли стандартную среду или создать настраиваемую среду, мы выбираем последнее. Спецификация теста представляет собой файл YAML, в котором перечислен набор команд оболочки, выполняемых на различных этапах выполнения теста. Это дает нам некоторый контроль над способом выполнения тестов на AWS.

А пока замените спецификацию по умолчанию следующим:

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

AWS использует концепцию, называемую пулами устройств. Каждое выполнение теста будет запускать все ваши тесты на всех устройствах в пуле. Нам просто нужно одно устройство для начала, поэтому мы создаем новый пул устройств с одним пикселем Google:

Затем следует шаг под названием Указать состояние устройства, который мы пока пропускаем (оставим значения по умолчанию). На последней странице мы можем просмотреть пробег. Давайте сократим время ожидания, чтобы не тратить драгоценные минуты устройства на случай, если что-то пойдет не так:

Наконец, мы можем запустить выполнение теста:

Вы можете увидеть пробег на приборной панели. Нажмите на нее и выберите наше тестовое устройство (Google Pixel), чтобы просмотреть журналы в реальном времени и прямую трансляцию с устройства (настройка займет несколько минут):

Это сценарий, который мы тестируем:

Если все пойдет хорошо, вы получите сообщение об успешном выполнении на странице результатов теста:

Примечание: обратите внимание на продолжительность выполнения теста. Существуют довольно значительные накладные расходы на настройку и отключение устройства (и некоторые другие из-за выполнения спецификации теста и инициализации WebDriver), которые необходимо учитывать при планировании выполнения тестов. Из-за этих накладных расходов AWS, как правило, намного лучше подходит для запуска более крупных наборов тестов за одно выполнение, чем меньших наборов тестов за несколько запусков. В некоторой степени это верно для всех облачных решений, но такие накладные расходы различаются для разных поставщиков и, следовательно, являются важным критерием выбора.

Что дальше?

Поздравляю! Вы успешно выполнили свои первые тесты Appium на AWS Device Farm. Давайте рассмотрим некоторые проблемы и посмотрим, как использование специальной спецификации тестирования может облегчить нашу жизнь. Затем мы продемонстрируем, как использовать их API для автоматизации процесса планирования тестов.

  1. Повторно загружайте тестовый пакет при каждом изменении

Вы можете повторно использовать тестовые пакеты, ранее загруженные в AWS Device Farm. Вам нужно только упаковать и загрузить их снова, если есть изменения. Однако в теории это звучит нормально, поскольку эти пакеты включают все, необходимое для запуска тестов, включая не только изменения в структуре или ее зависимостях, но также изменения в ваших тестах, ваших тестовых данных или вашей конфигурации теста. . Для изменения одного параметра (например, указания, какие тесты запускать) всегда требуется новый тестовый пакет.

Допустим, ваш набор тестов содержит 100 тестов, и вы хотите распределить их по 10 устройствам, чтобы сократить общее время выполнения. AWS и большинство других облачных провайдеров не поддерживают это сразу.

Наивный подход к решению этой проблемы в Device Farm заключается в создании 10 тестовых пакетов для каждого подмножества тестов, каждый из которых настроен на выполнение 10 различных тестов. Однако для этого требуется упаковка и загрузка нескольких больших, почти идентичных zip-файлов. Теперь предположим, что в следующий раз вы захотите распределить свои тесты по 20 устройствам или захотите выполнить несколько другой набор тестов. Вам всегда нужно заново создавать и загружать новые тестовые пакеты.

Именно так мы впервые использовали Device Farm до того, как они представили настраиваемые среды, и это было довольно болезненно. Постоянное создание и загрузка zip-файлов размером 100+ МБ делает конвейер CI намного более проблематичным, чем необходимо.

Пользовательские среды для спасения

Если вы еще раз взглянете на указанную выше спецификацию пользовательской среды, вы увидите, как мы можем использовать эту функцию, чтобы снять это ограничение. Информация в кодировке base64 включает нашу тестовую конфигурацию. Это позволяет нам настраивать запуски тестов, загружая относительно небольшой файл YAML (спецификацию теста), а не воссоздавать гораздо больший тестовый пакет. Мы кодируем конфигурацию во время создания тестовой спецификации. Когда он выполняется, мы декодируем его обратно в файл, который затем передается на выполнение в качестве параметра.

Для нескольких аргументов это может быть излишним, но для большего набора значений конфигурации строка в кодировке base64 оказывается довольно надежным и элегантным способом (это также избавляет нас от головной боли, связанной с экранированием специальных символов в YAML).

JustTestLah! использует Cucumber, поэтому, например, мы можем запускать разные сценарии, передавая отдельные теги Cucumber:

or

Пакет тестов может быть одинаковым для каждого прогона, изменяется только спецификация теста.

Дальнейшие улучшения

Мы можем пойти еще дальше и полностью избавиться от необходимости в тестовом пакете. Вместо этого мы настраиваем настраиваемую среду для получения необходимого кода и конфигурации из внешнего источника и полностью строим ее на экземпляре AWS.

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

2. Управляйте средой выполнения

Если вы выполняете тесты в своей инфраструктуре, вы полностью контролируете используемые инструменты и их версии. С AWS Device Farm все не так просто.

Среда по умолчанию по-прежнему использует Java 8 (которая на четыре основных выпуска уступает текущему JDK 12). В других библиотеках могут быть похожие проблемы, но для Java есть простое решение, которое можно загрузить и установить, добавив несколько строк в конфигурацию среды:

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

Выполнение тестов через API

Теперь, когда мы выполнили шаги по созданию выполнения теста вручную, давайте посмотрим, как мы можем использовать отличный AWS Java SDK (есть SDK для других языков программирования), чтобы автоматизировать процесс.

Для этого вам необходимо создать пользователя AWS с доступом к Device Farm и сгенерировать ключ доступа и секретный ключ. Я также рекомендую настроить AWS CLI и настроить его, позвонив:

Вам будет предложено ввести ключ доступа и секретный ключ, сгенерированный ранее. В качестве региона установите us-west-2. Ваши ключи будут храниться в вашем доме пользователя (под ~/.aws/credentials), и поставщик учетных данных по умолчанию, используемый в SDK, заберет их оттуда. Будьте осторожны, держите их как можно дальше от исходного кода.

Как только это будет сделано, давайте взглянем на код JAVA. Полный исходный код можно найти на GitHub. Для этой демонстрации мы вызываем AWS из класса бегуна JUnit (интересные элементы находятся внутри метода run). Обратите внимание, что вместо пула устройств мы используем концепцию, называемую фильтрами устройств, для определения используемого тестового устройства.

Теперь, даже если тесты выполняются в инфраструктуре AWS, мы можем заключить их в локальное выполнение JUnit (с некоторыми ограничениями) и выполнять их точно так же, как локальные тесты Appium или используя облачного провайдера с выполнением на стороне клиента.

Если тянуть JustTestLah! из Github и установите его в свой локальный репозиторий Maven, вызвав mvn install -DskipTests=true, вы можете запустить те же тесты, которые мы запланировали ранее через веб-консоль, вызвав:

Единственное значение, которое вам нужно установить в stackoverflow_aws.properties, - это ARN (имя ресурса Amazon) вашего проекта Device Farm. Вы можете легко найти это с помощью AWS CLI:

Обратите внимание, что путь к justtestlah.properties должен быть абсолютным (не стесняйтесь вносить свой вклад в JustTestLah!, Чтобы улучшить это). Вы можете найти демонстрационные конфигурации в разделе justtestlah-demos/demos. При использовании символической ссылки ln -s justtestlah-demos/demos /demos все команды работают, как показано. Либо измените путь по мере необходимости.

Вы можете легко пропустить загрузку нового пакета приложения или тестового пакета, указав ARN существующего в файле свойств:

cloudprovider=aws
aws.projectArn=xxx
aws.appPackageArn=yyy
aws.testPackageArn=zzz

Если вы хотите запустить те же тесты в Browserstack, вы просто должны передать другую конфигурацию (укажите адрес электронной почты Browserstack и ключ доступа в stackoverflow_browserstack.properties):

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

Как видите, при использовании этого метода облачный провайдер для выполнения тестов является не чем иным, как значением конфигурации. Вы можете легко переключаться между локальным исполнением, AWS Device Farm и Browserstack. Следующим уровнем инкапсуляции будет поддержка различных устройств на нескольких платформах и предоставление фреймворку возможности обрабатывать все остальное, т.е.выбирать облачного провайдера для каждого теста, который может предложить запрошенное устройство (и может сделать это быстрее всего).

Если у вас есть опыт работы с подобными установками или вы хотите поэкспериментировать с ними, напишите мне, пожалуйста.

Конфигурация

Помимо фильтров устройств, существует некоторая дополнительная конфигурация, которую вы можете определить для выполнения тестов AWS (это были настройки, которые мы пропустили во время Указать состояние устройства на веб-консоли):

Интеграция с Maven

Для немного другого способа интеграции AWS Device Farm (но с использованием того же Java SDK) вы можете взглянуть на мой Плагин Maven. Он предоставляет цели для каждого шага (загрузка пакета приложения, загрузка тестового пакета, планирование запуска и т. Д.), Что позволяет вам разделить их. Например, вы можете загружать новый пакет приложения каждый раз, когда появляется новая сборка, и загружать новый тестовый пакет каждый раз, когда в вашем тестовом коде происходит изменение. Само выполнение теста затем может быть независимым от обоих и просто повторно использовать последнее (или любое конкретное) приложение и тестовые пакеты.

Плагин Jenkins

Также существует плагин Jenkins для AWS Device Farm, но он не такой гибкий, как решения, описанные в этой статье.

Резюме

В этой статье мы продемонстрировали демонстрацию в стиле PoC того, как запускать тесты на AWS Device Farm примерно так же, как локально или на клиентских платформах выполнения, таких как Browserstack. Запуск тестов на AWS Device Farm и особенно их эффективная интеграция в процесс сборки - непростой процесс (для всех, кроме самых основных требований), и я надеюсь, что эти примеры помогут другим, кто сталкивается с аналогичными проблемами.

Когда что-то заработает, AWS становится надежным поставщиком облачных услуг для мобильной автоматизации, поэтому стоит выделиться и настроить все в соответствии с вашими потребностями.

Если у вас есть вопросы или комментарии, не стесняйтесь связаться со мной.