Вы можете запускать тесты в непрерывной интеграции (CI), чтобы отслеживать производительность с течением времени и распознавать снижение или улучшение производительности еще до того, как ваше приложение будет выпущено. На этой странице представлена основная информация о бенчмаркинге в CI.
Прежде чем приступить к сравнительному тестированию в CI, подумайте, чем сбор и оценка результатов отличаются от обычных тестов.
Нечеткие результаты
Хотя эталонные тесты представляют собой инструментальные тесты, результаты — это не просто «пройдено или не пройдено». Тесты предоставляют измерения времени для данного устройства, на котором они работают. Построение графиков результатов с течением времени позволяет отслеживать изменения и наблюдать шум в измерительной системе.
Используйте реальные устройства
Запустите тесты на физических устройствах Android. Хотя они могут работать на эмуляторах, это настоятельно не рекомендуется, поскольку это не отражает реалистичного пользовательского опыта и вместо этого предоставляет цифры, привязанные к операционной системе хоста и возможностям оборудования. Рассмотрите возможность использования реальных устройств или сервиса, позволяющего запускать тесты на реальных устройствах, например Firebase Test Lab .
Запустите тесты
Запуск тестов в рамках конвейера CI может отличаться от его локального запуска из Android Studio. Локально вы обычно запускаете интеграционные тесты Android с помощью одной задачи Gradle connectedCheck
. Эта задача автоматически создает ваш APK и тестовый APK, а также запускает тесты на устройствах, подключенных к серверу CI. При работе в CI этот поток обычно необходимо разделить на отдельные фазы.
Строить
Для библиотеки Microbenchmark запустите задачу Gradle assemble[VariantName]AndroidTest
, которая создаст тестовый APK, содержащий как код вашего приложения, так и тестируемый код.
Альтернативно, библиотека Macrobenchmark требует, чтобы вы создали целевой APK и протестировали APK отдельно. Поэтому запустите задачи Gradle :app:assemble[VariantName]
и :macrobenchmark:assemble[VariantName]
.
Установите и запустите
Эти шаги обычно выполняются без необходимости запуска задач Gradle. Обратите внимание: они могут быть абстрагированы в зависимости от того, используете ли вы службу, позволяющую запускать тесты на реальных устройствах.
Для установки используйте команду adb install
и укажите тестовый APK или целевой APK.
Запустите команду adb shell am
Instrument, чтобы запустить все тесты:
adb shell am instrument -w com.example.benchmark/androidx.benchmark.junit4.AndroidBenchmarkRunner
При использовании библиотеки Macrobenchmark используйте обычный androidx.test.runner.AndroidJUnitRunner
в качестве средства запуска инструментов.
Вы можете передать те же аргументы инструментария, что и в конфигурации Gradle, используя аргумент -e
. Все параметры аргументов инструментария см. в разделе «Аргументы инструментария Microbenchmark» или «Добавление аргументов инструментария для Macrobenchmark».
Например, вы можете установить аргумент dryRunMode
для запуска микробенчмарков в рамках процесса проверки запроса на включение. Если этот флаг включен, микробенчмарки выполняются только в одном цикле, проверяя их правильность, но не требуя слишком много времени для выполнения.
adb shell am instrument -w -e "androidx.benchmark.dryRunMode.enable" "true" com.example.benchmark/androidx.benchmark.junit4.AndroidBenchmarkRunner
Дополнительную информацию о том, как запускать инструментальные тесты из командной строки, см. в разделе «Выполнение тестов с помощью ADB» .
Блокировка часов
Плагин Microbenchmark Gradle предоставляет команду ./gradlew lockClocks
для блокировки тактовой частоты процессора корневого устройства. Это полезно для обеспечения стабильности, когда у вас есть доступ к корневым устройствам, например, к сборкам «userdebug». Вы можете повторить это с помощью сценария оболочки lockClocks.sh
, доступного в исходном коде библиотеки .
Вы можете либо запустить сценарий непосредственно с хоста Linux или Mac, либо отправить его на устройство с помощью нескольких команд adb:
adb push path/lockClocks.sh /data/local/tmp/lockClocks.sh adb shell /data/local/tmp/lockClocks.sh adb shell rm /data/local/tmp/lockClocks.sh
Если вы запускаете сценарий оболочки непосредственно на хосте, он отправляет эти команды на подключенное устройство.
Дополнительную информацию о том, почему полезно блокировать тактовую частоту ЦП, см. в разделе «Как получить согласованные тесты» .
Соберите результаты
Библиотеки тестирования выводят измерения в формате JSON , а также профилируют трассировки в каталог на устройстве под управлением Android после каждого запуска теста. Библиотека Macrobenchmark выводит несколько файлов трассировки perfetto: по одному на каждую измеренную итерацию каждого цикла MacrobenchmarkRule.measureRepeated
. Однако Microbenchmark создает только один файл трассировки для всех итераций каждого BenchmarkRule.measureRepeated
. Файлы трассировки профилирования также выводятся в этот же каталог.
Сохраните и найдите файлы
Если вы запускаете тесты с помощью Gradle, эти файлы автоматически копируются в каталог выходов вашего главного компьютера в build/outputs/connected_android_test_additional_output/debugAndroidTest/connected/
.
Если вы запускаете напрямую с помощью команды adb
, вам необходимо извлечь файлы вручную. По умолчанию отчеты сохраняются на устройстве в медиакаталоге внешнего хранилища тестируемого приложения. Для удобства библиотека печатает путь к файлу в Logcat. Обратите внимание, что выходная папка может отличаться в зависимости от версии Android, на которой выполняются тесты.
Benchmark: writing results to /storage/emulated/0/Android/media/com.example.macrobenchmark/com.example.macrobenchmark-benchmarkData.json
Вы также можете настроить место, где на устройстве будут сохраняться отчеты о тестировании, используя аргумент инструмента additionalTestOutputDir
. Эта папка должна быть доступна для записи вашему приложению.
adb shell am instrument -w -e additionalTestOutputDir /sdcard/Download/ com.example.benchmark/androidx.benchmark.junit4.AndroidBenchmarkRunner
В Android 10 (уровень API 29) и более поздних версиях тесты вашего приложения по умолчанию выполняются в изолированной программной среде хранилища, что предотвращает доступ вашего приложения к файлам за пределами каталога, специфичного для приложения. Чтобы иметь возможность сохранять в глобальный каталог, например /sdcard/Download
, передайте следующий аргумент инструментария:
-e no-isolated-storage true
Вы также должны явно разрешить устаревшие варианты хранения в манифесте вашего теста:
<application android:requestLegacyExternalStorage="true" ... >
Дополнительные сведения см. в разделе Временный отказ от хранилища с заданной областью .
Получить файлы
Чтобы получить сгенерированные файлы с устройства, используйте команду adb pull
, которая переносит указанный файл в текущий каталог на вашем хосте:
adb pull /storage/emulated/0/Android/media/com.example.macrobenchmark/com.example.macrobenchmark-benchmarkData.json
Чтобы получить все benchmarkData
из указанной папки, проверьте следующий фрагмент:
# The following command pulls all files ending in -benchmarkData.json from the directory
# hierarchy starting at the root /storage/emulated/0/Android.
adb shell find /sdcard/Download -name "*-benchmarkData.json" | tr -d '\r' | xargs -n1 adb pull
Файлы трассировки ( .trace
или .perfetto-trace
) сохраняются в той же папке, что и benchmarkData.json
, поэтому вы можете собирать их таким же образом.
Пример контрольных данных
Библиотеки тестов производительности генерируют файлы JSON, содержащие информацию об устройстве, на котором выполнялись тесты, и о фактических тестах, которые оно выполняло. Следующий фрагмент представляет сгенерированный файл JSON:
{
"context": {
"build": {
"brand": "google",
"device": "blueline",
"fingerprint": "google/blueline/blueline:12/SP1A.210812.015/7679548:user/release-keys",
"model": "Pixel 3",
"version": {
"sdk": 31
}
},
"cpuCoreCount": 8,
"cpuLocked": false,
"cpuMaxFreqHz": 2803200000,
"memTotalBytes": 3753299968,
"sustainedPerformanceModeEnabled": false
},
"benchmarks": [
{
"name": "startup",
"params": {},
"className": "com.example.macrobenchmark.startup.SampleStartupBenchmark",
"totalRunTimeNs": 4975598256,
"metrics": {
"timeToInitialDisplayMs": {
"minimum": 347.881076,
"maximum": 347.881076,
"median": 347.881076,
"runs": [
347.881076
]
}
},
"sampledMetrics": {},
"warmupIterations": 0,
"repeatIterations": 3,
"thermalThrottleSleepSeconds": 0
}
]
}
Дополнительные ресурсы
- Рекомендации по обнаружению снижения производительности см. в разделе Борьба с ухудшением производительности с помощью тестов в CI .
- Чтобы узнать, как настроить действия Github с помощью Firebase Test Lab, см. раздел Настройка макробенчмарков Jetpack для CI.
Рекомендуется для вас
- Примечание: текст ссылки отображается, когда JavaScript отключен.
- Рекомендации по повышению производительности SQLite
- Создавайте и измеряйте базовые профили без Macrobenchmark
- Зависшие частичные блокировки пробуждения