Konzepte und Jetpack Compose-Implementierung
Im Gegensatz zu den meisten Android-UI-Tests werden Makrobenchmark-Tests in einem separaten Prozess von der App selbst ausgeführt. Dies ist erforderlich, um beispielsweise den App-Prozess zu beenden und DEX-Bytecode in Maschinencode zu kompilieren.
Sie können den Status Ihrer App mit der UIAutomator-Bibliothek oder anderen Mechanismen steuern, mit denen die Ziel-App über den Testprozess gesteuert werden kann.
Espresso oder ActivityScenario können nicht für Makrobenchmarks verwendet werden, da sie in einem gemeinsamen Prozess mit der App ausgeführt werden müssen.
Im folgenden Beispiel wird ein RecyclerView anhand seiner Ressourcen-ID gesucht und mehrmals nach unten gescrollt:
Kotlin
@Test fun scrollList() { benchmarkRule.measureRepeated( // ... setupBlock = { uiAutomator { // Before starting to measure, navigate to the UI to be measured startIntent(Intent("$packageName.RECYCLER_VIEW_ACTIVITY")) } } ) { uiAutomator { val recycler = onElement { className == "androidx.recyclerview.widget.RecyclerView" } // Scroll down several times repeat(3) { recycler.fling(Direction.DOWN) } } } }
Java
@Test public void scrollList() { benchmarkRule.measureRepeated( // ... /* setupBlock */ scope -> { // Before measuring, navigate to the UI to be measured. val intent = Intent("$packageName.RECYCLER_VIEW_ACTIVITY") scope.startActivityAndWait(); return Unit.INSTANCE; }, /* measureBlock */ scope -> { UiDevice device = scope.getDevice(); UiObject2 recycler = device.findObject(By.res(scope.getPackageName(), "recycler")); // Set gesture margin to avoid triggering gesture navigation // with input events from automation. recycler.setGestureMargin(device.getDisplayWidth() / 5); // Fling the recycler several times. for (int i = 0; i < 3; i++) { recycler.fling(Direction.DOWN); } return Unit.INSTANCE; } ); }
Ihr Benchmark muss nicht durch die Benutzeroberfläche scrollen. Stattdessen kann beispielsweise eine Animation ausgeführt werden. Es muss auch nicht speziell UI Automator verwendet werden. Leistungsmesswerte werden erfasst, solange Frames gerendert werden.
Zu internen Bereichen der App wechseln
Manchmal möchten Sie Teile Ihrer App testen, auf die nicht direkt von außen zugegriffen werden kann. Das kann beispielsweise der Zugriff auf innere Aktivitäten sein, die mit exported=false gekennzeichnet sind, das Aufrufen eines Fragment oder das Wegwischen eines Teils der Benutzeroberfläche. Die Benchmarks müssen manuell wie ein Nutzer zu diesen Teilen der App navigieren.
Wenn Sie die Navigation manuell vornehmen möchten, ändern Sie den Code in setupBlock{} so, dass er den gewünschten Effekt enthält, z. B. das Tippen auf eine Schaltfläche oder das Wischen. Ihr measureBlock{} enthält nur die UI-Manipulation, die Sie tatsächlich vergleichen möchten:
Kotlin
@Test fun nonExportedActivityScrollList() { benchmarkRule.measureRepeated( // ... setupBlock = setupBenchmark() ) { // ... } } private fun setupBenchmark(): MacrobenchmarkScope.() -> Unit = { uiAutomator { // Before starting to measure, navigate to the UI to be measured startApp(TARGET_PACKAGE) // click a button to launch the target activity. onElement { textAsString() == "RecyclerView" }.click() // wait until the activity is shown waitForStableInActiveWindow() } }
Java
@Test public void scrollList() { benchmarkRule.measureRepeated( // ... /* setupBlock */ scope -> { // Before measuring, navigate to the default activity. scope.startActivityAndWait(); // Click a button to launch the target activity. // While you use resourceId here to find the button, you can also // use accessibility info or button text content. UiObject2 launchRecyclerActivity = scope.getDevice().findObject( By.res(packageName, "launchRecyclerActivity") ) launchRecyclerActivity.click(); // Wait until activity is shown. scope.getDevice().wait( Until.hasObject(By.clazz("$packageName.NonExportedRecyclerActivity")), 10000L ) return Unit.INSTANCE; }, /* measureBlock */ scope -> { // ... } ); }
Empfehlungen für Sie
- Hinweis: Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
- Makrobenchmark schreiben
- Makrobenchmark-Messwerte erfassen
- Microbenchmark