Aspectos básicos de las pruebas de apps para Android

En esta página, se describen los principios básicos de las pruebas de apps para Android, incluidas las prácticas recomendadas centrales y sus beneficios.

Beneficios de las pruebas

Probar la app es una parte integral del proceso de desarrollo. Cuando ejecutas pruebas de la app de manera coherente, puedes verificar la corrección, el comportamiento funcional y la usabilidad de la app 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 todos los errores del usuario o recorrer cada flujo de usuarios.

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

Tipos de pruebas en Android

Las aplicaciones para dispositivos móviles son complejas y deben funcionar bien en muchos entornos. Por lo tanto, existen muchos tipos de pruebas.

Asunto

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

  • Pruebas funcionales: ¿Mi app hace lo que debe?
  • Pruebas de rendimiento: ¿lo hace 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 pruebas de nivel inferior 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 app al mismo tiempo, como una pantalla completa o un flujo de usuarios.
  • Las pruebas de nivel intermedio se encuentran 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: Alcance de las pruebas en una aplicación típica.

Existen muchas formas de clasificar las pruebas. Sin embargo, la distinción más importante para los desarrolladores de apps es dónde 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 e instala junto con una app de prueba que inserta comandos y lee el estado. Las pruebas de instrumentación suelen ser pruebas de IU, en las que se inicia una app y luego se interactúa con ella.
  • Las pruebas locales se ejecutan en tu máquina de desarrollo o en un servidor, por lo que también se denominan pruebas del host. Por lo general, son pequeñas y rápidas, y aíslan el sujeto de prueba del resto de la app.
Las pruebas se pueden ejecutar como pruebas de instrumentación en un dispositivo o 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:

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

Ejemplos

En los siguientes fragmentos, se muestra cómo interactuar con la IU en una prueba de IU instrumentada que hace clic en un elemento y verifica que se muestre otro elemento.

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()

En este fragmento, se muestra parte de una prueba de unidad para un ViewModel (prueba local del host):

// 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)

Arquitectura que se puede probar

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

Una arquitectura que no se puede probar produce lo siguiente:

  • Pruebas más grandes, más lentas y menos confiables. Es posible que las clases que no se pueden probar en unidades deban cubrirse con pruebas de integración o de IU más grandes.
  • 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 puede ser poco realista.

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

Enfoques para la separación

Si puedes extraer parte de una función, clase o módulo del resto, probarlo 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.

Entre las técnicas de desvinculación comunes, se incluyen las siguientes:

  • Divide una app en capas, como Presentación, Dominio y Datos. 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 y muévela IU y la lógica empresarial a otro lugar, como a una capa de Composable, ViewModel o 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 la inserción de dependencias, incluso si no usas un framework de DI.

Próximos pasos

Ahora que ya sabes por qué deberías probar y los dos tipos principales de pruebas, puedes leer el artículo Qué debes probar, o bien obtener más información sobre Estrategias de prueba.

Como alternativa, si quieres crear tu primera prueba y aprender de forma práctica, consulta los codelabs de prueba.