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.
Verwenden Sie Modifier.testTag, um Compose-Elemente für UI Automator verfügbar zu machen.
Im folgenden Beispiel wird ein LazyColumn mit einem testTag verwendet:
@Composable
fun ProductListScreen() {
LazyColumn(
modifier = Modifier
.fillMaxSize()
.testTag("my_lazy_column") ) {
items(100) { index ->
ProductItem(index)
}
}
}
Im Test wird die testTag verwendet, um die LazyColumn zu finden und zu übertragen:
@Test
fun scrollList() {
benchmarkRule.measureRepeated(
packageName = "com.example.myapp",
metrics = listOf(FrameTimingMetric()),
iterations = 5,
setupBlock = {
uiAutomator {
pressHome()
startApp("com.example.myapp")
}
}
) {
uiAutomator {
// Find the Composable using its testTag mapped as a viewIdResourceName
val lazyColumn = onElement { viewIdResourceName == "my_lazy_column" }
// Fling the Compose list down
repeat(3) {
lazyColumn.fling(Direction.DOWN)
}
}
}
}
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 tief verschachtelten zusammensetzbaren Zielen navigieren
Manchmal möchten Sie einen bestimmten Bildschirm testen, der beim Start der App nicht sofort sichtbar ist, z. B. einen Detailbildschirm oder eine Zahlungsseite, die sich tief in Ihrem Jetpack Navigation-Graphen befindet.
Da Makrobenchmarks außerhalb des Prozesses ausgeführt werden, können Sie nicht direkt mit Ihrem NavController interagieren, um Bildschirme zu wechseln. Stattdessen muss Ihr Benchmark simulieren, dass ein Nutzer zu diesem Teil der App navigiert.
Verwenden Sie setupBlock für die Vorbereitungsschritte, z. B. das Klicken durch einen Onboarding-Ablauf oder auf eine Menüschaltfläche. So werden in measureBlock nur die Leistungsmesswerte des Zielbildschirms erfasst.
@Test
fun deepScreenScrollList() {
benchmarkRule.measureRepeated(
packageName = "com.example.myapp",
metrics = listOf(FrameTimingMetric()),
iterations = 5,
setupBlock = {
uiAutomator {
// 1. Start the app on the home screen
startApp("com.example.myapp")
// 2. Navigate to the internal screen by clicking a Compose component
// (e.g., a card that opens the target list view)
val settingsButton = onElement { viewIdResourceName == "go_to_list_button" }
settingsButton.click()
// 3. Wait until the target screen settles and is fully rendered
waitForStableInActiveWindow()
}
}
) {
uiAutomator {
// The actual benchmark measurement starts here on the target screen
val lazyColumn = onElement { viewIdResourceName == "my_lazy_column" }
lazyColumn.fling(Direction.DOWN)
}
}
}
Zusätzliche Ressourcen
Weitere Informationen zum Testen finden Sie in den folgenden Ressourcen.
Dokumentation
Inhalte ansehen
Empfehlungen für Sie
- Hinweis: Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
- Makrobenchmark schreiben
- Makrobenchmark-Messwerte erfassen
- Microbenchmark