W trybie ciągłej integracji (CI) możesz przeprowadzać testy porównawcze, aby śledzić wydajność na przestrzeni czasu i wykrywać spadki lub ulepszenia, jeszcze zanim aplikacja zostanie wydana. Ta strona zawiera podstawowe informacje o testach porównawczych w CI.
Zanim zaczniesz korzystać z analizy porównawczej w CI, zastanów się, czym różni się zbieranie i ocenianie wyników od zwykłych testów.
Wyniki przybliżone
Chociaż testy porównawcze są testami instrumentalnymi, ich wyniki to nie wszystko. Porównania pozwalają na pomiar czasu w przypadku danego urządzenia, na którym działają. Wykresy wyników w czasie umożliwiają monitorowanie zmian i szumów w systemie pomiarów.
Korzystaj z prawdziwych urządzeń
przeprowadzanie testów porównawczych na fizycznych urządzeniach z Androidem; Można ich używać w emulatorach, ale zdecydowanie odradzamy ich stosowanie, ponieważ nie pokazują realistycznego doświadczenia użytkownika. Zamiast tego zawierają liczby powiązane z możliwościami systemu operacyjnego hosta i sprzętu. Rozważ wykorzystanie prawdziwych urządzeń lub usługi, która umożliwia przeprowadzanie testów na rzeczywistych urządzeniach, np. Laboratorium Firebase.
Przeprowadź testy porównawcze
Uruchamianie testów porównawczych w ramach potoku CI może się różnić od uruchamiania go lokalnie z Androida Studio. Lokalnie przeprowadza się zwykle testy integracji z Androidem z 1 zadaniem Gradle connectedCheck
. To zadanie automatycznie tworzy plik APK i testowy plik APK oraz przeprowadza testy na urządzeniach połączonych z serwerem CI. Jeśli działa on w CI, zwykle trzeba podzielić go na osobne fazy.
Budowanie
W przypadku biblioteki Microbenchmark uruchom zadanie Gradle assemble[VariantName]AndroidTest
, które utworzy testowy plik APK zawierający zarówno kod Twojej aplikacji, jak i testowany kod.
Biblioteka Macrobenchmark wymaga też utworzenia docelowego pliku APK i samodzielnego przetestowania go. W związku z tym uruchamiaj zadania :app:assemble[VariantName]
i :macrobenchmark:assemble[VariantName]
Gradle.
Zainstaluj i uruchom
Te kroki zwykle wykonuje się bez konieczności uruchamiania zadań Gradle. Pamiętaj, że mogą one być wyodrębnione w zależności od tego, czy używasz usługi, która umożliwia przeprowadzanie testów na rzeczywistych urządzeniach.
Aby przeprowadzić instalację, użyj polecenia adb install
i podaj testowy plik APK lub docelowy plik APK.
Uruchom polecenie instrumentu adb shell am
, aby wykonać wszystkie testy porównawcze:
adb shell am instrument -w com.example.benchmark/androidx.benchmark.junit4.AndroidBenchmarkRunner
Gdy korzystasz z biblioteki Macroporównania, jako uruchamiających instrumentów używaj zwykłego narzędzia androidx.test.runner.AndroidJUnitRunner
.
Za pomocą argumentu -e
możesz przekazywać te same argumenty instrumentacji co w konfiguracji Gradle. Wszystkie opcje argumentów instrumentacji znajdziesz w sekcjach Argumenty instrumentacji mikroporównawczej i Dodawanie argumentów narzędziowych do analizy porównawczej makr.
Możesz na przykład ustawić argument dryRunMode
, aby uruchamiać mikroporównania w ramach procesu weryfikacji żądania pull. Gdy ta flaga jest włączona, mikroporównania działają tylko w pojedynczej pętli i sprawdzają, czy działają prawidłowo, ale ich wykonanie nie trwa zbyt długo.
adb shell am instrument -w -e "androidx.benchmark.dryRunMode.enable" "true" com.example.benchmark/androidx.benchmark.junit4.AndroidBenchmarkRunner
Więcej informacji o przeprowadzaniu testów instrumentów z poziomu wiersza poleceń znajdziesz w artykule Przeprowadzanie testów przy użyciu ADB.
Zablokuj zegary
Wtyczka Microbenchmark Gradle udostępnia polecenie ./gradlew lockClocks
blokujące zegary procesora w przypadku urządzenia z dostępem do roota. Jest to przydatne dla zapewnienia stabilności, gdy masz dostęp do urządzeń z dostępem do roota, na przykład kompilacji „userdebug”. Możesz to powielić za pomocą skryptu powłoki lockClocks.sh
, który jest dostępny w źródle biblioteki.
Możesz uruchomić skrypt bezpośrednio z hosta z systemem Linux lub Mac albo przekazać go na urządzenie za pomocą kilku poleceń 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
Jeśli uruchomisz skrypt powłoki bezpośrednio na hoście, wyśle on te polecenia do połączonego urządzenia.
Więcej informacji o tym, dlaczego warto blokować zegary procesora, znajdziesz w artykule o uzyskaniu spójnych testów porównawczych.
Zebranie wyników
Biblioteki testów porównawczych podają wyniki pomiarów w JSON wraz z logami profilowania do katalogu na urządzeniu z Androidem po każdym przeprowadzeniu analizy porównawczej. Biblioteka Macrobenchmark generuje wiele plików śledzenia, po jednym na zmierzoną iterację każdej pętli MacrobenchmarkRule.measureRepeated
. Natomiast mikroporównanie tworzy tylko 1 plik śledzenia dla wszystkich iteracji każdego BenchmarkRule.measureRepeated
. W tym samym katalogu są również dane wyjściowe profilowania.
Zapisz i zlokalizuj pliki
Jeśli przeprowadzisz testy porównawcze za pomocą Gradle, pliki te zostaną automatycznie skopiowane do katalogu danych wyjściowych komputera hosta w folderze build/outputs/connected_android_test_additional_output/debugAndroidTest/connected/
.
Jeśli uruchamiasz aplikację bezpośrednio za pomocą polecenia adb
, pliki musisz pobrać ręcznie. Domyślnie raporty są zapisywane na urządzeniu, w katalogu multimediów w zewnętrznej pamięci masowej testowanej aplikacji. Dla wygody biblioteka wydrukuje
ścieżkę pliku w Logcat. Pamiętaj, że folder wyjściowy może się różnić w zależności od wersji Androida, na której działają testy porównawcze.
Benchmark: writing results to /storage/emulated/0/Android/media/com.example.macrobenchmark/com.example.macrobenchmark-benchmarkData.json
Lokalizację, w której na urządzeniu są zapisywane raporty analizy porównawczej, możesz też skonfigurować, używając argumentu instrumentacji additionalTestOutputDir
. Aplikacja musi mieć możliwość zapisu w tym folderze.
adb shell am instrument -w -e additionalTestOutputDir /sdcard/Download/ com.example.benchmark/androidx.benchmark.junit4.AndroidBenchmarkRunner
Na Androidzie 10 (poziom interfejsu API 29) i nowszych testy aplikacji są domyślnie przeprowadzane w piaskownicy pamięci masowej, co uniemożliwia aplikacji dostęp do plików spoza katalogu związanego z aplikacją. Aby móc zapisać pliki w katalogu globalnym, takim jak /sdcard/Download
, przekaż ten argument instrumentacji:
-e no-isolated-storage true
Musisz też wyraźnie zezwolić na używanie starszych opcji miejsca na dane w pliku manifestu testu porównawczego:
<application android:requestLegacyExternalStorage="true" ... >
Więcej informacji znajdziesz w artykule o tymczasowym wyłączaniu miejsca na dane o zakresie.
Pobierz pliki
Aby pobrać wygenerowane pliki z urządzenia, użyj polecenia adb pull
, które pobierze określony plik do bieżącego katalogu na hoście:
adb pull /storage/emulated/0/Android/media/com.example.macrobenchmark/com.example.macrobenchmark-benchmarkData.json
Aby pobrać wszystkie pliki benchmarkData
z określonego folderu, sprawdź ten fragment kodu:
# 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
Pliki śledzenia (.trace
lub .perfetto-trace
) są zapisywane w tym samym folderze co benchmarkData.json
, możesz więc zbierać je w ten sam sposób.
Przykład danych analizy porównawczej
Biblioteki porównawcze generują pliki JSON zawierające informacje o urządzeniu, na którym uruchomiono testy porównawcze, oraz rzeczywiste testy porównawcze. Ten fragment kodu reprezentuje wygenerowany plik 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
}
]
}
Dodatkowe materiały
- Wskazówki dotyczące wykrywania spadków wydajności znajdziesz w artykule zwalczanie regresji za pomocą testów porównawczych w CI.
- Aby dowiedzieć się, jak skonfigurować działania w GitHubie z Laboratorium Firebase, przeczytaj artykuł o konfigurowaniu makr Jetpack Macrobenchmarks dla CI.
Polecane dla Ciebie
- Uwaga: tekst linku jest wyświetlany, gdy JavaScript jest wyłączony
- Sprawdzone metody dotyczące wydajności SQLite
- Tworzenie i pomiar profili bazowych bez użycia Macroporównanie
- Ciągłe częściowe blokady uśpienia