W przeciwieństwie do większości testów interfejsu Androida testy Macrobenchmark są przeprowadzane w osobnym procesie niż sama aplikacja. Jest to konieczne, aby umożliwić takie działania jak zatrzymanie procesu aplikacji i kompilowanie z kodu bajtowego DEX do kodu maszynowego.
Stan aplikacji możesz kontrolować za pomocą biblioteki UIAutomator lub innych
mechanizmów, które mogą sterować aplikacją docelową z procesu testowego.
Aby udostępnić elementy Compose do UI Automator, użyj Modifier.testTag.
W tym przykładzie używamy LazyColumn z testTag:
@Composable
fun ProductListScreen() {
LazyColumn(
modifier = Modifier
.fillMaxSize()
.testTag("my_lazy_column") ) {
items(100) { index ->
ProductItem(index)
}
}
}
Test używa testTag, aby znaleźć LazyColumn i przeciągnąć go:
@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)
}
}
}
}
Test porównawczy nie musi przewijać interfejsu. Może na przykład uruchomić animację. Nie musi też używać UI Automator. Zbiera dane o skuteczności, dopóki generowane są klatki.
Przechodzenie do głęboko zagnieżdżonych miejsc docelowych
Czasami możesz chcieć przeprowadzić test porównawczy konkretnego ekranu, który nie jest od razu widoczny po uruchomieniu aplikacji, np. ekranu szczegółów lub strony płatności znajdującej się głęboko w grafie nawigacji Jetpack.
Ponieważ Macrobenchmark działa poza procesem, nie możesz bezpośrednio wchodzić w interakcję z NavController, aby przełączać ekrany. Zamiast tego test porównawczy musi symulować użytkownika przechodzącego do tej części aplikacji.
Użyj setupBlock, aby wykonać kroki przygotowawcze, np. kliknąć przycisk menu lub przejść przez proces wprowadzający. Dzięki temu measureBlock rejestruje dane o skuteczności tylko ekranu docelowego.
@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)
}
}
}
Dodatkowe materiały
Więcej informacji o testowaniu znajdziesz w tych materiałach.
Dokumentacja
Wyświetlanie treści
Polecane dla Ciebie
- Uwaga: tekst linku jest wyświetlany, gdy język JavaScript jest wyłączony.
- Pisanie testu Macrobenchmark
- Rejestrowanie danych Macrobenchmark
- Microbenchmark