Guías prácticas
Alternativas a Idling Resources en pruebas de Compose : las APIs waitUntil (actualizado)
Lectura de 3 minutos
En este artículo, aprenderás a usar la API de prueba waitUntil en Compose para esperar a que se cumplan determinadas condiciones. En algunas situaciones, esta es una buena alternativa a la hora de usar recursos inactivos.
[Actualización del 2023] Resumen: usa las nuevas APIs waitUntil para sincronizar las pruebas de Compose (versión 1.4.0 o posterior).
¿Qué es la sincronización?
Una forma de clasificar las pruebas es por su ámbito. Las pruebas pequeñas, o pruebas unitarias, se centran en pequeñas partes de tu aplicación, mientras que las pruebas grandes, o de extremo a extremo, abarcan una gran parte de tu aplicación. Puedes consultar información sobre este y otros tipos de pruebas en la documentación de pruebas, que se ha actualizado recientemente.
Pulsa Intro o haz clic para ver la imagen a tamaño completo
La sincronización es el mecanismo que indica a la prueba cuándo debe ejecutar la siguiente operación. Cuanto mayor sea el fragmento de código que elijas verificar, más difícil será sincronizarlo con la prueba. En las pruebas unitarias, es fácil tener el control total de la ejecución del código que se va a verificar. Sin embargo, a medida que ampliamos el alcance para incluir más clases, módulos y capas, resulta complicado para el framework de pruebas saber si la aplicación está en medio de una operación o no.
Pulsa Intro o haz clic para ver la imagen a tamaño completo
androidx.test y, por extensión, Compose Test, usan algunos trucos internos para que no tengas que preocuparte demasiado por esto. Por ejemplo, si el hilo principal está ocupado, la prueba se pausa hasta que pueda ejecutar la siguiente línea.
Sin embargo, no pueden saberlo todo. Por ejemplo, si cargas datos en un subproceso en segundo plano, es posible que el framework de pruebas ejecute la siguiente operación demasiado pronto, lo que provocará que la prueba falle. La peor situación es cuando esto ocurre solo en un pequeño porcentaje de las veces, lo que hace que la prueba sea inestable.
Opción 1: Recursos inactivos
Los recursos inactivos son una función de Espresso que te permite, como desarrollador, decidir cuándo está ocupada la aplicación. Tienes dos formas de usarlos:
1. Instalarlos en el framework o la biblioteca que realiza un trabajo que la prueba no puede ver.
Un buen ejemplo de esto es RxIdler, que encapsula un programador RxJava. Esta es la forma preferida de registrar recursos inactivos, ya que te permite mantener la configuración de las pruebas separada del código de prueba.
2. Modificar el código que se está probando para exponer explícitamente información sobre si tu aplicación está ocupada o no.
Por ejemplo, puedes modificar tu repositorio (o un test double) para indicar que está ocupado mientras carga datos de una fuente de datos:
No es lo ideal, ya que contaminas el código de producción o creas dobles de prueba complicados, y hay situaciones en las que son difíciles de instalar. Por ejemplo, ¿cómo usarías Idling Resources en un flujo de Kotlin? ¿Cuál es la última actualización?
En su lugar, podemos esperar.
Opción 2: Esperar a que pasen cosas… de la forma incorrecta
La carga de datos suele ser rápida, sobre todo cuando se usan datos falsos, así que ¿por qué perder tiempo con recursos inactivos cuando puedes hacer que la prueba espere un par de segundos?
Esta prueba se ejecutará más lento de lo necesario o fallará. Cuando tienes cientos o miles de pruebas de interfaz de usuario, quieres que las pruebas sean lo más rápidas posible.
Además, a veces los emuladores o los dispositivos no funcionan correctamente y se bloquean, lo que hace que la operación tarde un poco más de 2000 ms y que se interrumpa la compilación. Cuando tienes cientos de pruebas, esto se convierte en un problema enorme.
Opción 3: Esperar de la forma correcta
Si no quieres modificar el código que estás probando para que muestre cuándo está ocupado, otra opción es esperar a que se cumpla una condición determinada en lugar de esperar un periodo de tiempo arbitrario.
En Compose, puedes usar la función waitUntil, que toma otra función que produce un valor booleano.
Actualización del 22/03/2023: a partir de Compose 1.4.0, hemos añadido un nuevo conjunto de APIs waitUntil:
[Antes de la versión 1.4.0: usa estas funciones auxiliares: waitUntilExists y waitUntilNodeCount]
…y úsalos de esta forma:
Usa estas APIs solo cuando necesites sincronizar tu prueba con la interfaz de usuario. Sincronizar cada instrucción de prueba contamina el código de prueba innecesariamente, lo que dificulta su mantenimiento.
¿Cuándo deberías usarlo? Un buen caso práctico es cargar datos de un observable (con LiveData, Kotlin Flow o RxJava). Si tu interfaz de usuario necesita recibir varias actualizaciones antes de considerarse inactiva, puedes simplificar la sincronización con waitUntil.
Por ejemplo, cuando recoges un flujo de una vista:
Y emites varios elementos:
Si repository tarda un tiempo indeterminado en devolver el primer resultado, el framework de pruebas considerará que "Cargando" es el estado de inactividad (el valor inicial asignado en collectAsState) y continuará con la siguiente instrucción.
Por lo tanto, puedes hacer que la prueba sea mucho más fiable si te aseguras de que la interfaz de usuario no muestra el indicador de carga:
¡Que disfrutes… espera… con las pruebas!
Licencia de fragmentos de código:
Copyright 2022 Google LLC. SPDX-License-Identifier: Apache-2.0
Seguir leyendo
-
Instrucciones
En esta entrada, vamos a centrarnos en algo más atractivo visualmente: implementar un efecto de foco sobre la vista previa de la cámara usando la detección de caras como base para el efecto.
Jolanda Verhoef • Lectura de 8 minutos
-
Instrucciones
Google es consciente de que el consumo excesivo de batería es una de las principales preocupaciones de los usuarios de Android, por lo que ha tomado medidas importantes para ayudar a los desarrolladores a crear aplicaciones más eficientes.
Alice Yuan • Lectura de 8 minutos
-
Instrucciones
Queríamos mostrarte ejemplos de funciones basadas en IA que usan modelos en el dispositivo y en la nube, así como inspirarte para que crees experiencias atractivas para tus usuarios.
Thomas Ezan, Ivy Knight • Tiempo de lectura: 2 min
Mantente al día
Recibe cada semana en tu bandeja de entrada las últimas novedades sobre el desarrollo para Android.