Нет смысла подслащивать пилюлю: UI-тесты на Android могут быть медленными, особенно если со временем у вас накопилось их много.

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

Краткая история эмулятора Android

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

Затем, в 2013 году, появился Genymotion с эмулятором, который фактически запускал Android на x86 в виртуальной машине, размещенной в VirtualBox, что, очевидно, обеспечивало лучшую производительность. Так что многие разработчики перешли на Genymotion — всего лишь с некоторыми оговорками (преимущественно насчет цены).

Примерно в 2016 году Google резко улучшил стандартный эмулятор Android, позволив ему использовать аппаратную виртуализацию x86, и производительность продолжала повышаться с течением времени. Разработчикам потребовалось какое-то время, чтобы восстановить доверие к предоставленным инструментам, но всё с легкостью трансформировалось в лучший опыт эмуляции, который можно получить на десктопе. Совсем недавно, в 2019 году, произошел массивный скачок в плане производительности и функций благодаря Project Marble.

Добудьте более мощную машину для разработки (само собой)

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

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

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

Отключите анимацию

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

Отключить анимацию можно двумя способами. Традиционный способ — зайти в скрытые настройки разработчика и вручную отключить все три типа анимации. Это даже первый шаг инструкции по настройке Espresso.

Связанная документация утверждает, что причина заключается в том, чтобы избежать нестабильности тестов, но преимущества в производительности также реальны. Я даже видел несколько статей, которые рекомендуют конечным пользователям отключить анимацию, чтобы их устройства “ощущались” как более быстрые.

Еще один, более новый способ отключить анимацию — это настройка в build.gradle вашего приложения. Вы можете установить для android.testOptions.animationDisabled значение true:

android {
    testOptions {
        animationsDisabled true
    }
}

После этого плагин Android Gradle автоматически организует отключение анимации во время запуска инструментальных тестов через Gradle. Он делает это, передавая аргумент --no-window-animation в интерфейс командной строки тест-раннера. (Я буду неоднократно ссылаться к этой командной строке, когда буду писать о производительности тестов Android — она стоит того, чтобы в ней разобраться, даже если вы не работаете с ней напрямую.)

Обратите внимание, что этот параметр не действует при работе с устройствами, на которых анимация уже отключена в настройках разработчика. Также он не действует в облачных сервисах для тестирования, таких как Firebase Test Lab, где анимация уже отключена тем же образом.

Выбирайте меньшие экраны с более низкой плотностью пикселей

При настройке эмулятора для его использования в тестировании ваши UI-тесты будут выполняться быстрее на виртуальных экранах с меньшим количеством пикселей. Логика здесь в том, что задействование меньшего количества пикселей автоматически преобразуется в повышение производительности. Когда вы выбираете аппаратную конфигурацию для нового эмулятора в Android Studio, пользовательский интерфейс продвигает Pixel-подобные устройства, но если вы прокрутите вниз, то увидите варианты устройств с низкой и средней плотностью пикселей и меньшими экранами.

Почти никто не скроллит так далеко вниз, чтобы увидеть конфигурации с маленькими экранами!

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

Попробуйте “безголовый” вариант

У современных вариантов эмулятора Android теперь есть “безголовая” (headless) сборка. Такая сборка не будет открывать окно при запуске. Ее обычно используют при тестировании в рамках непрерывной интеграции на виртуализированных машинах, которые не имеют дисплеев. Однако вы также можете запустить безголовую сборку у себя на десктопе. Запуск headless-сборки уменьшит объем памяти и процессора, необходимый для работы эмулятора, что может пригодиться где-нибудь еще на вашей машине (или может использоваться для запуска другого эмулятора, чтобы вы могли рассредоточить тесты).

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

В документации и замечаниях к версии для безголовых сборок говорится о двоичном файле под названием “emulator-headless” в установочном каталоге SDK. Когда я писал это, используя эмулятор версии 30.0.5, мне не удалось найти ничего подобного. Но вы можете работать в безголовом режиме в командной строке с помощью emulator -no-window. Если у вас нет опыта запуска эмулятора через интерфейс командной строки, вы можете просмотреть документацию по интерфейсу командной строки эмулятора.

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

Читайте также:

Читайте нас в Telegram, VK и Яндекс.Дзен


Перевод статьи Doug Stevenson: “Reconsider the Android emulator for faster testing”

Предыдущая статьяСовременные шаблоны проектирования архитектуры
Следующая статьяСтроим собственный блокчейн на Python и разбираемся в его особенностях