Użyj biblioteki Macroporównanie do testowania większych przypadków użycia aplikacji, w tym uruchamiania aplikacji i skomplikowanych manipulacji interfejsem, takich jak przewijanie obszaru RecyclerView
czy uruchamianie animacji. Jeśli chcesz testować mniejsze obszary kodu, skorzystaj z biblioteki Microbenchmark. Tutaj pokazujemy, jak skonfigurować
bibliotekę Macroporównanie.
Biblioteka generuje wyniki testów porównawczych zarówno do konsoli Android Studio, jak i w pliku JSON z bardziej szczegółowymi informacjami. Zawiera też pliki śledzenia, które można wczytać i przeanalizować w Android Studio.
Użyj biblioteki makrporównawczych w środowisku ciągłej integracji (CI) zgodnie z opisem w sekcji Analiza porównawcza w ciągłej integracji.
Za pomocą Analizy porównawczej możesz wygenerować profile bazowe. Najpierw skonfiguruj bibliotekę Macroporównanie, a następnie możesz utworzyć profil podstawowy.
Konfigurowanie projektu
W przypadku funkcji IDE, które integrują się z Macrobenchmark, zalecamy korzystanie z Macroporównania w najnowszej wersji Android Studio.
Konfigurowanie modułu Makroporównań
Analiza porównawcza makr wymaga modułu com.android.test
– niezależnego od kodu aplikacji – który odpowiada za uruchamianie testów na temat aplikacji.
W Android Studio dostępny jest szablon, który upraszcza konfigurację modułu Macrobenchmark. Szablon modułu analizy porównawczej automatycznie tworzy w Twoim projekcie moduł do pomiaru aplikacji skompilowanej przez moduł aplikacji, w tym przykładową analizę porównawczą.
Aby użyć szablonu do utworzenia nowego modułu:
Kliknij prawym przyciskiem myszy projekt lub moduł w panelu Projekt w Android Studio i wybierz Nowy > Moduł.
W panelu Szablony kliknij Analiza porównawcza. Możesz dostosować aplikację docelową (czyli aplikację do analizy porównawczej) oraz nazwę pakietu i modułu na potrzeby nowego modułu Macroporównanie.
Kliknij Zakończ.
Konfigurowanie aplikacji
Aby przeprowadzić test porównawczy aplikacji – tzw. celu testu porównawczego makr, musi ona mieć typ profileable
, co umożliwia odczytywanie szczegółowych informacji z śladu bez wpływu na wydajność. Kreator modułu automatycznie dodaje tag <profileable>
do pliku AndroidManifest.xml
aplikacji.
Upewnij się, że aplikacja docelowa zawiera pakiet ProfilerInstaller
w wersji 1.3 lub nowszej, którego biblioteka Macroporównanie jest potrzebna, aby umożliwić przechwytywanie profilu, resetowanie i czyszczenie pamięci podręcznej narzędzia cieniowania.
Skonfiguruj aplikację z testu porównawczego jak najbliżej wersji produkcyjnej lub wersji produkcyjnej. Skonfiguruj go jako bez możliwości debugowania, a najlepiej z włączoną minifikacją, co zwiększa wydajność. Zwykle robi się to przez utworzenie kopii wariantu wersji. Ta funkcja działa tak samo, ale jest podpisywana lokalnie kluczami debugowania.
Możesz też użyć polecenia initWith
, aby polecić Gradle wykonanie tej czynności za Ciebie:
Kotlin
buildTypes { getByName("release") { isMinifyEnabled = true isShrinkResources = true proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt")) } create("benchmark") { initWith(getByName("release")) signingConfig = signingConfigs.getByName("debug") } }
Odlotowy
buildTypes { getByName("release") { isMinifyEnabled = true isShrinkResources = true proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) // In real app, this would use its own release keystore signingConfig = signingConfigs.getByName("debug") } }
Aby mieć pewność, że w ramach testu porównawczego zostaną zarówno kompilacje, jak i przetestowanie właściwej wersji aplikacji (jak widać na Rysunku 2), wykonaj te czynności:
- Przeprowadź synchronizację z Gradle.
- Otwórz panel Tworzenie wariantów.
- Wybierz wersję porównawczą aplikacji i modułu Macroporównanie.
(Opcjonalnie) Skonfiguruj aplikację składającą się z wielu modułów
Jeśli aplikacja ma więcej niż 1 moduł Gradle, upewnij się, że skrypty kompilacji wiedzą, który wariant kompilacji ma być skompilowany. Dodaj właściwość matchingFallbacks
do typu kompilacji benchmark
modułów :macrobenchmark
i :app
. Pozostałe moduły Gradle mogą mieć taką samą konfigurację jak poprzednio.
Kotlin
create("benchmark") { initWith(getByName("release")) signingConfig = signingConfigs.getByName("debug") matchingFallbacks += listOf("release") }
Odlotowy
benchmark { initWith buildTypes.release signingConfig signingConfigs.debug matchingFallbacks = ['release'] }
Bez niego nowo dodany typ kompilacji benchmark
powoduje błąd kompilacji i wyświetla ten komunikat o błędzie:
> Could not resolve project :shared.
Required by:
project :app
> No matching variant of project :shared was found.
...
Wybierając warianty kompilacji w projekcie, wybierz benchmark
dla modułów :app
i :macrobenchmark
oraz release
dla pozostałych modułów, które masz w aplikacji, jak widać na rysunku 3:
Więcej informacji znajdziesz w artykule Korzystanie z zarządzania zależnościami zależnymi od wariantów.
(Opcjonalnie) Skonfiguruj smaki produktów
Jeśli w aplikacji masz ustawionych wiele smaków produktów, skonfiguruj moduł :macrobenchmark
tak, aby wiedział, jaki smak produktu Twojej aplikacji powinien utworzyć i porównać.
Przykłady na tej stronie wykorzystują 2 rodzaje produktów w module :app
: demo
i production
, jak widać w tym fragmencie:
Kotlin
flavorDimensions += "environment" productFlavors { create("demo") { dimension = "environment" // ... } create("production") { dimension = "environment" // ... } }
Odlotowy
flavorDimensions 'environment' productFlavors { demo { dimension 'environment' // ... } production { dimension 'environment' // ... } }
Bez tej konfiguracji może wystąpić błąd kompilacji podobny do tego w przypadku wielu modułów Gradle:
Could not determine the dependencies of task ':macrobenchmark:connectedBenchmarkAndroidTest'.
> Could not determine the dependencies of null.
> Could not resolve all task dependencies for configuration ':macrobenchmark:benchmarkTestedApks'.
> Could not resolve project :app.
Required by:
project :macrobenchmark
> The consumer was configured to find a runtime of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'benchmark', attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '7.3.0'. However we cannot choose between the following variants of project :app:
- demoBenchmarkRuntimeElements
- productionBenchmarkRuntimeElements
All of them match the consumer attributes:
...
W dwóch poniższych sekcjach opisano sposoby konfigurowania testu porównawczego z wieloma rodzajami produktów.
Użyj brakującej strategii wymiaru
Określenie missingDimensionStrategy
w module defaultConfig
w module :macrobenchmark
informuje system kompilacji, że ma się przełączyć na wymiar smak. Określ, których wymiarów nie ma w module.
W tym przykładzie jako wymiar domyślny używany jest rodzaj production
:
Kotlin
defaultConfig { missingDimensionStrategy("environment", "production") }
Odlotowy
defaultConfig { missingDimensionStrategy "environment", "production" }
Dzięki temu moduł :macrobenchmark
może tworzyć i przeprowadzać testy porównawcze tylko o określonym smaku produktu. Jest to przydatne, gdy wiesz, że tylko jeden rodzaj produktu ma odpowiednią konfigurację do analizy porównawczej.
Definiowanie smaków produktów w module :macrobenchmark
Jeśli chcesz tworzyć różne smaki produktów i je porównywać, zdefiniuj je w module :macrobenchmark
. Określ ją podobnie jak w module :app
, ale przypisz productFlavors
tylko do elementu dimension
. Żadne inne ustawienia nie są wymagane:
Kotlin
flavorDimensions += "environment" productFlavors { create("demo") { dimension = "environment" } create("production") { dimension = "environment" } }
Odlotowy
flavorDimensions 'environment' productFlavors { demo { dimension 'environment' } production { dimension 'environment' } }
Po zdefiniowaniu i zsynchronizowaniu projektu wybierz w panelu Warianty kompilacji odpowiedni wariant kompilacji, jak widać na ilustracji 4:
Więcej informacji znajdziesz w artykule Naprawianie błędów kompilacji związanych z dopasowaniem wariantu.
Tworzenie klasy analizy porównawczej
Testy porównawcze są przeprowadzane za pomocą interfejsu MacrobenchmarkRule
interfejsu API reguły JUnit4 w bibliotece Macrobenchmark. Zawiera metodę measureRepeated
, która pozwala określić różne warunki uruchomienia i porównania aplikacji docelowej.
Musisz określić przynajmniej: packageName
aplikacji docelowej, zakres danych metrics
, które chcesz zmierzyć, i liczbę iterations
, którą musi przeprowadzić test porównawczy.
Kotlin
@LargeTest @RunWith(AndroidJUnit4::class) class SampleStartupBenchmark { @get:Rule val benchmarkRule = MacrobenchmarkRule() @Test fun startup() = benchmarkRule.measureRepeated( packageName = TARGET_PACKAGE, metrics = listOf(StartupTimingMetric()), iterations = DEFAULT_ITERATIONS, setupBlock = { // Press home button before each run to ensure the starting activity isn't visible. pressHome() } ) { // starts default launch activity startActivityAndWait() } }
Java
@LargeTest @RunWith(AndroidJUnit4.class) public class SampleStartupBenchmark { @Rule public MacrobenchmarkRule benchmarkRule = new MacrobenchmarkRule(); @Test public void startup() { benchmarkRule.measureRepeated( /* packageName */ TARGET_PACKAGE, /* metrics */ Arrays.asList(new StartupTimingMetric()), /* iterations */ 5, /* measureBlock */ scope -> { // starts default launch activity scope.startActivityAndWait(); return Unit.INSTANCE; } ); } }
Informacje o wszystkich opcjach dostosowywania testów porównawczych znajdziesz w sekcji Dostosowywanie testów porównawczych.
Przeprowadź test porównawczy
Uruchom test w Android Studio, by zmierzyć skuteczność aplikacji na urządzeniu. Testy porównawcze możesz przeprowadzać w taki sam sposób jak dowolne inne @Test
z użyciem działania rynku znajdującego się obok klasy lub metody testowej, jak pokazano na rys. 5.
Wszystkie testy porównawcze w module Gradle możesz też uruchamiać z poziomu wiersza poleceń, wykonując polecenie connectedCheck
:
./gradlew :macrobenchmark:connectedCheck
Aby uruchomić pojedynczy test, wykonaj te czynności:
./gradlew :macrobenchmark:connectedCheck -P android.testInstrumentationRunnerArguments.class=com.example.macrobenchmark.startup.SampleStartupBenchmark#startup
Informacje o tym, jak uruchamiać i monitorować testy porównawcze w trybie ciągłej integracji, znajdziesz w sekcji Analiza porównawcza w ciągłej integracji.
Wyniki testu porównawczego
Po udanym przeprowadzeniu analizy porównawczej dane są wyświetlane bezpośrednio w Android Studio i wyjściowe na potrzeby użycia CI w pliku JSON. Każda zmierzona iteracja rejestruje osobny ślad systemu. Wyniki śledzenia możesz otworzyć, klikając linki w panelu Wyniki testu, jak pokazano na rys. 6:
Po wczytaniu logu czasu Android Studio poprosi o wybranie procesu do analizy. Ten wybór jest wstępnie wypełniany przez docelowy proces aplikacji, jak widać na rys. 7:
Po wczytaniu pliku śledzenia Studio wyniki pojawią się w narzędziu do profilowania procesora:
Raporty JSON i wszystkie ślady profilowania są również automatycznie kopiowane z urządzenia do hosta. Są one zapisywane na hoście w tej lokalizacji:
project_root/module/build/outputs/connected_android_test_additional_output/debugAndroidTest/connected/device_id/
Ręczne uzyskiwanie dostępu do plików śledzenia
Jeśli chcesz przeanalizować plik śledzenia za pomocą narzędzia Perfetto, musisz wykonać dodatkowe czynności. Perfetto umożliwia zbadanie wszystkich procesów realizowanych na urządzeniu podczas śledzenia, a profilowanie procesora w Android Studio ogranicza inspekcję do 1 procesu.
Jeśli wywołujesz testy w Android Studio lub z wiersza poleceń Gradle, pliki śledzenia są automatycznie kopiowane z urządzenia do hosta. Są one zapisywane na hoście w tej lokalizacji:
project_root/module/build/outputs/connected_android_test_additional_output/debugAndroidTest/connected/device_id/TrivialStartupBenchmark_startup[mode=COLD]_iter002.perfetto-trace
Gdy masz plik śledzenia w systemie hosta, możesz go otworzyć w Android Studio, klikając Plik > Otwórz w menu. Wyświetli się widok narzędzia do profilowania z poprzedniej sekcji.
Błędy konfiguracji
Jeśli aplikacja jest nieprawidłowo skonfigurowana (można ją debugować lub nie profilować), Macrobenchmark zwraca błąd, zamiast zgłaszać nieprawidłowy lub niepełny pomiar. Możesz pominąć te błędy za pomocą argumentu androidx.benchmark.suppressErrors
.
Macroporównanie zwraca też błędy, gdy próbujesz zmierzyć emulator lub urządzenie o niskiej baterii, co może obniżyć dostępność rdzeni i szybkość zegara.
Dostosuj testy porównawcze
Funkcja measureRepeated
akceptuje różne parametry, które wpływają na dane zbierane przez bibliotekę, sposób uruchamiania i kompilowania aplikacji oraz na liczbę iteracji testów porównawczych.
Rejestruj dane
Dane to główny typ informacji wyodrębnionych z testów porównawczych. Dostępne są te wskaźniki:
Więcej informacji o danych znajdziesz w artykule Rejestrowanie danych analizy porównawczej.
Popraw dane z logów czasu za pomocą zdarzeń niestandardowych
Przydatne może być instrumentowanie aplikacji za pomocą niestandardowych zdarzeń logu czasu, które są widoczne w pozostałej części raportu śledzenia i pomagają wskazywać problemy charakterystyczne dla Twojej aplikacji. Więcej informacji o tworzeniu niestandardowych zdarzeń logu czasu znajdziesz w sekcji Definiowanie zdarzeń niestandardowych.
Tryb kompilacji
Analiza porównawcza makr może określać element CompilationMode
, który określa, jaka część aplikacji musi być wstępnie skompilowana z kodu bajtowego DEX (formatu kodu bajtowego w pliku APK) na kod maszyny (podobnie do wstępnie skompilowanego C++).
Domyślnie testy porównawcze makr są przeprowadzane w usłudze CompilationMode.DEFAULT
, która instaluje profil podstawowy (jeśli jest dostępny) na Androidzie 7 (poziom interfejsu API 24) i nowszych.
Jeśli używasz Androida 6 (poziom interfejsu API 23) lub starszego, tryb kompilacji w pełni kompiluje plik APK jako domyślne działanie systemowe.
Możesz zainstalować profil podstawowy, jeśli aplikacja docelowa zawiera zarówno profil podstawowy, jak i bibliotekę ProfileInstaller
.
W Androidzie 7 i nowszych możesz dostosować CompilationMode
tak, aby wpływało na liczbę wstępnej kompilacji na urządzeniu i symulujące różne poziomy kompilacji z wyprzedzeniem lub buforowania JIT. Zobacz CompilationMode.Full
, CompilationMode.Partial
, CompilationMode.None
i CompilationMode.Ignore
.
Ta funkcja opiera się na poleceniach kompilacji ART. Każdy test porównawczy usuwa dane profilowe przed rozpoczęciem, co pozwala uniknąć zakłóceń między testami porównawczymi.
Tryb uruchamiania
Aby rozpocząć aktywność, możesz przekazać wstępnie zdefiniowany tryb uruchamiania: COLD
, WARM
lub HOT
. Ten parametr zmienia sposób uruchamiania działania i stan procesu na początku testu.
Więcej informacji o typach uruchamiania znajdziesz w artykule Czas uruchomienia aplikacji.
Próbki
Przykładowy projekt jest dostępny w MacrobenchmarkSample w repozytorium na GitHubie.
Prześlij opinię
Aby zgłosić problemy lub przesłać prośbę o dodanie funkcji do Jetpack Macrobenchmark, skorzystaj z publicznego narzędzia do śledzenia problemów.
Polecane dla Ciebie
- Uwaga: tekst linku jest wyświetlany, gdy JavaScript jest wyłączony
- Rejestrowanie danych analizy porównawczej makr
- Tworzenie profili podstawowych {:#using-profile-rules}
- Zautomatyzuj pomiary za pomocą biblioteki Macroporównanie {:#measuring-Optimization}