Обходим ограничения в Calabash-Android с UIAutomator

в 9:37, , рубрики: android, calabash, qa, qa automation, Блог компании Badoo, разработка мобильных приложений, Разработка под android, Тестирование мобильных приложений, метки:

enter image description here

Appium и Calabash — одни из самых популярных фреймворков для автоматизации тестирования Android-приложений. У каждого, конечно, есть свои преимущества и недостатки. Их основные ограничения:

  • Calabash: может управлять только пользовательским интерфейсом, который является частью тестового приложения, в частности, нет поддержки тестирования уведомлений;

  • Appium: не может вызывать backdoor-методы в приложениях наподобие Calabash (эти методы очень полезны для настройки состояния тестируемого приложения).

Мы в Badoo пользовались Calabash для автоматизации тестирования, когда Appium только начинал развиваться. Это очень стабильный инструмент, и он до сих пор работает быстрее Appium, так что мы не собираемся мигрировать. Но чтобы автоматизировать такое многофункциональное приложение, как Badoo, нам пришлось обойти ограничение Calabash на работу только с интерфейсом тестового приложения.

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

В этой статье я расскажу, как мы решили возникшую проблему с помощью добавления в Calabash поддержки UIAutomator2. Если вы слишком нетерпеливы, то скажу по секрету, что в конце есть ссылка на готовый к использованию Ruby Gem.

Осознание проблемы

Давайте посмотрим на высокоуровневую архитектуру Calabash-Android:

enter image description here

Calabash-Android-Server использует фреймворк Robotium, который в свою очередь для управления приложением использует Android-фреймворк Instrumentation. Instrumentation даёт Robotium (а следовательно, и Calabash) доступ к среде исполнения, что позволяет тому управлять интерфейсом приложения и осуществлять вызов методов извне.

Но это также означает, что Robotium может управлять лишь пользовательским интерфейсом, являющимся частью кода приложения. В Appium нет такого ограничения, поскольку он использует UIAutomator.

Решение проблемы

Фреймворк Google Instrumentation является частью вспомогательной Android-библиотеки для тестирования. Он работает в контексте приложения, показывает все взаимодействия системы с приложением и, значит, может управлять ими. На базе Instrumentation построены такие популярные фреймворки для тестирования, как Robotium и Espresso.

Кроме того, Robotium используется в серверной части Calabash-Android и поэтому имеет доступ к информации Instrumentation. Также частью Instrumentation в своё время стал UIAutomator 2.0, что даёт возможность его использования внутри сервера Calabash-Android.

С помощью CalabashInstrumentationTestRunner Ruby-клиент Calabash запускает Instrumentation через ADB. В сервере Calabash CalabashInstrumentationTestRunner является расширением Android-класса Instrumentation. Это объект Instrumentation, передаваемый в Robotium Solo. Благодаря UIAutomator 2, он может быть использован для создания нового объекта UIDevice, который способен управлять всем устройством.

enter image description here

Вот как я пришёл к решению проблемы:

1) Добавил библиотеку UIAutomator в сервер Calabash-Android

Я клонировал проект Сalabash-Android-Server и добавил JAR uiautomator2 в папку lib.

2) Инстанцировал объект UIDevice

В файле InstrumentationBackend.java я создал метод для инстанцирования объекта UIDevice из UIAutomator.

public static UiDevice getUiDevice() {
    if (instrumentation.getUiAutomation() == null) {
        throw new NullPointerException("uiAutomation==null: did you forget to set '-w' flag for 'am instrument'?");
    }
    if(uiDevice == null) {
        uiDevice = UiDevice.getInstance(instrumentation);
    }
    return uiDevice;
}

3) Добавил новую команду с помощью API UIAutomator2

Совсем несложно добавить в Calabash-Android-Server новую команду. Все команды, которые вы используете в коде Ruby, мапятся в интерфейс Actions:

sh.calaba.instrumentationbackend.actions

Давайте реализуем действие для открытия панели уведомлений:

public class PullNotification implements Action {
    @Override
    public Result execute(String... args) {
        InstrumentationBackend.getUiDevice().openNotification();
        return new Result(true);
    }

    @Override
    public String key() {
        return "pull_notification";
    }
}

В этом примере метод key() использован для наименования команды, которая будет использоваться Ruby-клиентом Calabash. При вызове этой команды клиентом она запускает метод execute().

4) Запустил измерение (Instrumentation) с флагом -w

Клонировал Ruby-клиент из https://github.com/calabash/calabash-android. Пропатчил lib/calabash-android/operations.rb и добавил флаг -w в запуск измерения с использованием команды ADB. Как это сделать, можно посмотреть в этом коммите.

Вышеописанные примеры можно посмотреть в моём форке:

Работающий пример:

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

  • Клонируйте оба репозитория из вышеупомянутого форка в каталог того же уровня.
    git clone https://github.com/rajdeepv/calabash-android
    git clone https://github.com/rajdeepv/calabash-android-server

  • В обоих репозиториях переключитесь на ветку ‘uiautomator’.

  • Перейдите в папку ruby-gem в репозитории calabash-android и соберите Ruby Gem с помощью команды bundle exec rake build.

  • Включите этот Gem в свой проект.

  • Измените start_test_server_in_background на start_test_server_in_background(with_uiautomator: true).

  • Команда вытягивания панели уведомлений: perform_action('pull_notification').

  • Чтобы «коснуться» нотификации с известным фрагментом текста, используйте perform_action('uiautomator_touch_partial_text', ‘my partial text')

Готовый к использованию Ruby Gem:

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

Заключение

Мне потребовалось приложить некоторые усилия, чтобы углубиться в код Calabash-Android-Server, понять, как он работает, и исследовать возможность решения проблемы. С первой попытки это сделать не удалось, но в процессе работы я узнал некоторые секреты Instrumentation. Когда-нибудь я ими поделюсь с вами.

Хотя этот пример посвящён автоматизации push-уведомлений с помощью Calabash, тот же подход можно применить к любой задаче, с которой вы столкнётесь в автоматизационных фреймворках на базе Calabash:

  • тестирование виджетов вашего приложения для домашнего экрана;

  • обработка намерений (Intent) с помощью диалоговых блоков Complete action using в Android-приложениях;

  • тестирование взаимодействия со сторонними приложениями, запущенными из вашего приложения.

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

Автор: Badoo

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js