Kontroluj aplikację na podstawie analizy porównawczej

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.

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