Aspectos básicos de las pruebas de apps para Android

En esta página, se describen los principios básicos de prueba de apps para Android, incluido el de las principales prácticas recomendadas y sus beneficios.

Beneficios de las pruebas

Probar la app es una parte integral del proceso de desarrollo. Ejecutando pruebas puedes verificar si la app es correcta, el comportamiento y la usabilidad antes de lanzarla públicamente.

Para probar tu app manualmente, navega por ella. Podrías usar diferentes dispositivos y emuladores, cambiar el idioma del sistema y tratar de generar cada error del usuario o atravesar cada flujo del usuario.

Sin embargo, las pruebas manuales no escalan, y puede ser fácil pasar por alto regresiones en el comportamiento de tu app. Las pruebas automatizadas implican el uso de herramientas que realizan pruebas por ti, lo cual es más rápido, más repetible y, en general, te brinda más comentarios prácticos sobre tu app en una etapa anterior del desarrollo el proceso de administración de recursos.

Tipos de pruebas en Android

Las aplicaciones para dispositivos móviles son complejas y deben funcionar bien en muchos entornos. Como hay muchos tipos de pruebas.

Asunto

Por ejemplo, hay diferentes tipos de pruebas según el tema:

  • Pruebas funcionales: ¿Mi app hace lo que se supone que debe hacer?
  • Pruebas de rendimiento: ¿Lo hacen de forma rápida y eficiente?
  • Pruebas de accesibilidad: ¿Funcionan bien con los servicios de accesibilidad?
  • Pruebas de compatibilidad: ¿Funciona bien en todos los dispositivos y niveles de API?

Alcance

Las pruebas también varían según el tamaño o el grado de aislamiento:

  • Las pruebas de unidades o pequeñas solo verifican una parte muy pequeña de la app. como un método o una clase.
  • Las pruebas de extremo a extremo o grandes verifican partes más grandes de la aplicación a través de la al mismo tiempo, como una pantalla completa o un flujo de usuarios.
  • Las pruebas de nivel intermedio están en el medio y verifican la integración entre dos o más unidades.
Las pruebas pueden ser pequeñas, medianas o grandes.
Figura 1: Prueba de alcances en una aplicación típica.

Hay muchas formas de clasificar las pruebas. Sin embargo, la distinción más importante para desarrolladores de apps es donde se ejecutan las pruebas.

Pruebas instrumentadas en comparación con pruebas locales

Puedes ejecutar pruebas en un dispositivo Android o en otra computadora:

  • Las pruebas de instrumentación se ejecutan en un dispositivo Android, ya sea físico o emulado. La app se compila y se instala junto con una app de prueba que inserta comandos y lee el estado. Por lo general, las pruebas de instrumentación son pruebas de IU, en las que se inicia una app de interactuar con él.
  • Las pruebas locales se ejecutan en tu máquina de desarrollo o en un servidor, por lo que también llamadas pruebas del host. Por lo general, son pequeños y rápidos, y aíslan el sujeto de prueba en el resto de la aplicación.
Las pruebas se pueden ejecutar como pruebas de instrumentación en un dispositivo o como pruebas locales en tu máquina de desarrollo.
Figura 2: Diferentes tipos de pruebas según dónde se ejecuten.

No todas las pruebas de unidades son locales, y no todas las pruebas de extremo a extremo se ejecutan en un dispositivo. Por ejemplo:

  • Big local test: Puedes usar un simulador de Android que se ejecute localmente. como Robolectric.
  • Prueba instrumentada pequeña: Puedes verificar que el código funcione bien con un del framework, como una base de datos SQLite. Puedes ejecutar esta prueba en varios dispositivos para comprobar la integración con varias versiones de SQLite.

Ejemplos

Los siguientes fragmentos demuestran cómo interactuar con la IU en un prueba de IU instrumentada que hace clic en un elemento y verifica que otro .

Espresso

// When the Continue button is clicked
onView(withText("Continue"))
    .perform(click())

// Then the Welcome screen is displayed
onView(withText("Welcome"))
    .check(matches(isDisplayed()))

IU de Compose

// When the Continue button is clicked
composeTestRule.onNodeWithText("Continue").performClick()

// Then the Welcome screen is displayed
composeTestRule.onNodeWithText("Welcome").assertIsDisplayed()

Este fragmento muestra parte de una prueba de unidades para un ViewModel (local, del lado del host) prueba):

// Given an instance of MyViewModel
val viewModel = MyViewModel(myFakeDataRepository)

// When data is loaded
viewModel.loadData()

// Then it should be exposing data
assertTrue(viewModel.data != null)

Cómo definir una estrategia de prueba

En una situación ideal, deberías probar cada línea de código de tu app en todos los dispositivos compatibles con tu app. Por desgracia, este enfoque es demasiado lento y y costosos de ser prácticos.

Una buena estrategia de prueba encuentra un equilibrio adecuado entre la fidelidad de una prueba, su velocidad y confiabilidad. La similitud del entorno de pruebas con un dispositivo real determina la fidelidad de la prueba. Las pruebas de mayor fidelidad se ejecutan en emulados o en el mismo dispositivo físico. Es posible que se ejecuten pruebas de menor fidelidad en la JVM de tu estación de trabajo local. Las pruebas de alta fidelidad suelen ser más lentas y requieren más recursos, por lo que no todas las pruebas deben ser de alta fidelidad.

Pruebas inestables

Se producen errores incluso en ejecuciones de pruebas diseñadas e implementadas correctamente. Por ejemplo: cuando se ejecuta una prueba en un dispositivo real, es posible que se inicie una actualización automática en medio de una prueba y hacen que falle. Las condiciones de carrera sutiles en el código ocurren solo un pequeño porcentaje de las veces. Las pruebas que no superen el 100% de tiempo son indecisos.

Arquitectura que se puede probar

Con una arquitectura de app que se puede probar, el código sigue una estructura que te permite para probar fácilmente diferentes partes de forma aislada. Las arquitecturas que se pueden probar tienen otras ventajas, como mejor legibilidad, capacidad de mantenimiento, escalabilidad su reutilización.

Una arquitectura que no se puede probar produce lo siguiente:

  • Pruebas más grandes, más lentas y más inestables. Es posible que las clases que no se pueden probar en unidades incluir pruebas de integración o IU más amplias.
  • Menos oportunidades para probar diferentes situaciones. Las pruebas más grandes son más lentas, por lo que probar todos los estados posibles de una app podría resultar poco realista.

Para obtener más información sobre los lineamientos de arquitectura, consulta la guía de la app arquitectura.

Enfoques para la separación

Si puedes extraer parte de una función, clase o módulo del resto, probar es más fácil y eficaz. Esta práctica se conoce como separación, y es el concepto más importante para la arquitectura que se puede probar.

Las técnicas de desacoplamiento comunes incluyen las siguientes:

  • Divide una app en capas, como Presentación, Dominio y Datos. Puedes También puedes dividir una app en módulos, uno por función.
  • Evita agregar lógica a entidades que tengan dependencias grandes, como actividades y fragmentos. Usa estas clases como puntos de entrada al framework Mueve la lógica empresarial y de IU a otro lugar, como a un elemento componible, ViewModel o capa de dominio.
  • Evita las dependencias del framework directas en las clases que contienen lógica empresarial. Por ejemplo, no uses contextos de Android en ViewModels.
  • Haz que las dependencias sean fáciles de reemplazar. Por ejemplo, usa interfaces en lugar de implementaciones concretas. Usa Inserción de dependencias, incluso si no usas un framework de DI.

Próximos pasos

Ahora que sabes por qué deberías hacer pruebas y los dos tipos principales de pruebas, puedes Consulta Qué debes probar.

Como alternativa, si quieres crear tu primera prueba y aprender haciendo, marca consulta los codelabs de prueba.