A diferencia de la mayoría de las pruebas de IU de Android, las pruebas de Macrobenchmark se ejecutan en un proceso independiente de la app. Esto es necesario para habilitar acciones como detener el proceso de la app y compilar desde el código de bytes DEX hasta el código máquina.
Puedes controlar el estado de tu app con la biblioteca de UIAutomator o algún otro
mecanismo que pueda controlar la app objetivo desde el proceso de prueba.
Para exponer elementos de Compose a UI Automator, usa Modifier.testTag.
En el siguiente ejemplo, se usa un LazyColumn con un testTag:
@Composable
fun ProductListScreen() {
LazyColumn(
modifier = Modifier
.fillMaxSize()
.testTag("my_lazy_column") ) {
items(100) { index ->
ProductItem(index)
}
}
}
La prueba usa el testTag para encontrar el LazyColumn y deslizarlo:
@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)
}
}
}
}
No es necesario que las comparativas se desplacen por la IU; En cambio, pueden ejecutar una animación, por ejemplo. Tampoco es necesario que usen específicamente UIAutomator. Recopilan métricas de rendimiento, siempre y cuando se produzcan fotogramas.
Cómo navegar a destinos componibles profundos
A veces, es posible que quieras comparar una pantalla específica que no sea visible de inmediato cuando se inicia la app, como una pantalla de detalles o una página de confirmación de la compra en lo profundo de tu gráfico de navegación de Jetpack.
Debido a que Macrobenchmark se ejecuta fuera del proceso, no puedes interactuar directamente con tu NavController para intercambiar pantallas. En cambio, tu comparativa debe simular que un usuario navega a esa parte de la app.
Usa el setupBlock para controlar los pasos de preparación, como hacer clic en un flujo de incorporación o en un botón de menú. De esta manera, tu measureBlock captura las métricas de rendimiento solo de la pantalla de destino.
@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)
}
}
}
Recursos adicionales
Para obtener más información sobre las pruebas, consulta los siguientes recursos.
Documentación
Contenido de Views
Recomendaciones para ti
- Nota: El texto del vínculo se muestra cuando JavaScript está desactivado
- Cómo escribir una macrocomparativa
- Cómo capturar métricas de macrocomparativas
- Microcomparativas