Тестировать Android-приложение онлайн значит, что телефон находится где-то в другом месте. Вы подключаетесь к нему по сети, ставите сборку, смотрите на экран в браузере и снимаете логи через adb, будто кабель воткнут в ваш ноутбук. Если всё сделать правильно, это заменяет большую часть того, что даёт ящик с тестовыми телефонами. Если плохо, получится медленный эмулятор с лишними шагами.
В этом гайде одна сборка проходит путь от APK до логов падения на трёх версиях Android. Здесь команды, которые я запускаю каждую неделю, ошибки установки, которые вы встретите, а в конце честный список мест, где физический телефон всё ещё лучше.
Подготовьте сборку
Начните со сборки, которую можно поставить из командной строки. Для первого прохода хватит debug-сборки:
./gradlew assembleDebug ls app/build/outputs/apk/debug/
Две проверки сэкономят время позже. Первая касается ABI. Если в приложении есть нативный код, убедитесь, что в APK лежат библиотеки arm64-v8a. Телефоны, собранные по моделям настоящих аппаратов, работают на arm64 и, в отличие от x86-образов эмулятора на вашем ноутбуке, не транслируют код, собранный под другую архитектуру.
unzip -l app/build/outputs/apk/debug/app-debug.apk | grep "lib/"
Вторая проверка касается флага testOnly. Когда вы жмёте Run в Android Studio, IDE помечает APK атрибутом android:testOnly="true", и обычный adb install такую сборку не принимает. У сборок из assembleDebug этого флага нет. Если у вас есть только сборка из IDE, ставьте её через adb install -t.
Если релизный артефакт у вас в виде app bundle, превратите его в набор APK для подключённого телефона с помощью bundletool:
bundletool build-apks --bundle=app-release.aab --output=app.apks --connected-device bundletool install-apks --apks=app.apks
Без --ks bundletool подписывает отладочным ключом. Для тестов это нормально, но поверх копии, подписанной релизным ключом, такая сборка не встанет.
Берите три версии Android, а не одну
Один телефон скрывает большую часть проблем совместимости, потому что Android меняет поведение двумя способами. Одни изменения касаются всех приложений на новом релизе. Другие включаются, только когда вы поднимаете targetSdkVersion. Три версии ловят большинство и тех и других:
- Самая старая версия, которую вы ещё поддерживаете, или ближайшая к ней. В 2026 году разумный нижний порог для большинства приложений — Android 12.
- Версия с самой большой долей в вашей собственной аналитике, часто 14 или 15.
- Самый новый релиз, 16 или 17, где первыми проявляются изменения, привязанные к target: обязательный edge-to-edge и predictive back.
Полный список того, что меняется между каждой парой версий, длинный. Чек-лист по версиям есть в гайде о тестировании приложения на разных версиях Android.
Шаг 1: создайте телефоны
В сервисе облачных телефонов вы выбираете версию Android и модель, и примерно через минуту телефон готов. Называйте каждый по версии, например qa-12, qa-14 и qa-16, чтобы логи и скриншоты было легко читать и через неделю. Если вы делаете это скриптом из CI, те же шаги через API описаны в разделе о первом устройстве.
Выбирайте модели, которые реально есть у ваших пользователей. Бюджетный телефон с экраном 720p и флагман с 1440p ломают разные макеты, поэтому разная плотность экрана на трёх версиях даёт больше покрытия за то же время.
Шаг 2: установите сборку
Доставить APK на телефон можно тремя способами: загрузить в панели управления в браузере, отправить через REST API или выполнить adb install через ADB-реле. Первые два описаны в гайде по приложениям. Для adb включите реле для своего IP-адреса, как написано в документации по ADB, и подключитесь:
adb connect HOST:PORT adb -s HOST:PORT install -r app-debug.apk
Ошибки установки почти всегда сводятся к одной из пяти, и строка ошибки подсказывает, к какой:
| Ошибка | Причина | Что делать |
|---|---|---|
INSTALL_FAILED_NO_MATCHING_ABIS | нет нативных библиотек под ABI телефона | добавить arm64-v8a в abiFilters |
INSTALL_FAILED_TEST_ONLY | APK собран кнопкой Run в IDE | adb install -t или сборка через Gradle |
INSTALL_FAILED_UPDATE_INCOMPATIBLE | установлена копия, подписанная другим ключом | сначала adb uninstall старой копии |
INSTALL_FAILED_DEPRECATED_SDK_VERSION | target ниже API 23 на Android 14, ниже 24 на 15 и новее | поднять targetSdkVersion |
INSTALL_PARSE_FAILED_MANIFEST_MALFORMED | у компонента с intent-фильтром нет android:exported на 12 и новее | объявить exported у каждого такого компонента |
Шаг 3: прогоните smoke-тест, который можно повторить
Проходите один и тот же сценарий одинаково на каждой версии, чтобы различия, которые вы видите, были различиями Android, а не того, как вы нажимали. Мой проход проверяет шесть вещей:
- Холодный старт.
am start -WвыводитTotalTimeв миллисекундах. Сравнивайте его между версиями, а не с физическим флагманом. - Первый запуск. Ставьте без
-g, чтобы каждый запрос разрешения появился так, как его видит новый пользователь. - Уход в фон и возврат. Нажмите Home, откройте два других приложения, вернитесь.
- Смерть процесса. Когда приложение в фоне,
am killзавершает процесс так же, как это делает система при нехватке памяти. При возврате приложение должно восстановить экран и его состояние. - Конфигурация. Тёмная тема, крупный шрифт, другой масштаб экрана.
- Навигация назад. Жест «назад» с каждого экрана верхнего уровня.
Команды, где в S лежит адрес устройства:
S=HOST:PORT adb -s $S shell am force-stop com.example.app adb -s $S shell am start -W -n com.example.app/.MainActivity adb -s $S shell input keyevent KEYCODE_HOME adb -s $S shell am kill com.example.app adb -s $S shell cmd uimode night yes adb -s $S shell settings put system font_scale 1.3 adb -s $S shell wm density 560 adb -s $S shell wm density reset
Перед следующим проходом верните размер шрифта командой settings put system font_scale 1.0 и выключите тёмную тему через cmd uimode night no или просто сбросьте телефон.
Шаг 4: читайте логи
Очищайте буфер перед каждым сценарием и читайте только свой процесс:
adb -s $S logcat -c adb -s $S shell am start -W -n com.example.app/.MainActivity adb -s $S logcat -d --pid=$(adb -s $S shell pidof -s com.example.app)
Pid меняется при каждом перезапуске процесса, поэтому падение на старте под новым pid не появится. Читайте вместо этого буфер падений. В нём хранятся Java- и нативные падения всех процессов:
adb -s $S logcat -d -b crash adb -s $S logcat -d AndroidRuntime:E "*:S"
Для ANR logcat даёт только заголовок. adb bugreport report.zip собирает трассировки потоков на тот момент вместе с состоянием системы. Это занимает минуту-две, и именно этот файл нужно прикладывать к тикету.
Держите три лога рядом. Предупреждение, которое есть только на самой новой версии, обычно означает изменение, привязанное к target. Падение на всех трёх версиях означает ошибку в вашем коде.
Шаг 5: сбрасывайте телефон между прогонами
pm clear стирает данные вашего приложения и оставляет всё остальное: другие приложения, изменённые настройки, аккаунт Google. Для чистого сравнения между наборами тестов сбрасывайте телефон в чистое состояние, а pm clear оставьте для быстрых повторов внутри одного набора.
Когда проход стабилен, ему место в CI. На странице о тестировании приложений те же шаги показаны вызовами API. Инструментальные тесты — это обычные команды adb, поэтому они запускаются на любом устройстве, до которого дотягивается adb:
adb -s $S shell am instrument -w -e class com.example.LoginTest \ com.example.app.test/androidx.test.runner.AndroidJUnitRunner
Где заканчивается онлайн-тестирование
Будьте честны в том, чего телефон в дата-центре вам не скажет:
- Качество камеры, автофокус, реальный дрейф GPS и биометрические датчики.
- Производительность графики. Виртуализированный Android рисует через транслирующие или программные драйверы, поэтому время кадра и число подвисаний не переносятся на физический телефон.
- Расход батареи и троттлинг от нагрева.
- Софт производителя. Оптимизаторы батареи и настройки автозапуска на некоторых марках останавливают фоновую работу так, как стоковый Android этого не делает.
- Радиомодули: оплата по NFC, сопряжение по Bluetooth, функции оператора.
Для этих проверок держите два-три физических телефона, а широкую матрицу гоняйте онлайн.
Бесплатные способы начать
«Бесплатное тестирование на реальных устройствах онлайн» обычно означает одно из трёх. Android Emulator на вашем компьютере ничего не стоит и отлично подходит для цикла «поправил и запустил». Публичные облака устройств дают небольшие бесплатные квоты на физические телефоны, в основном для автоматических прогонов. Сервисы облачных телефонов обычно предлагают пробный период: в Clousd первые 30 минут бесплатны и без карты, этого хватит, чтобы поставить сборку и сделать первый smoke-проход, подробнее на странице о бесплатном пробном периоде.


