Skip to content
This repository was archived by the owner on May 30, 2023. It is now read-only.

Implementación

Juan Camilo Bages edited this page Dec 9, 2018 · 12 revisions

Flujos

La aplicación cuenta con 4 vistas principales, estas son:

  • Fillup: Crear un registro de tanqueo
  • History: Ver histórico de tanqueo
  • Statistics: Ver estadísticas de tanqueo
  • Vehicle: Ver información del carro

Dicho esto, se realizaron inicialmente 4 features para probar cada uno de las vistas principales. A continuación se describe cada uno de los features con los flujos realizados sobre los mismos:

Fillup Feature

En este feature se hicieron pruebas sobre la vista de Fillup. Se probaron distintos escenarios para agregar registros de manera invalida como lo son:

  • Campos en blanco
  • Campos insertando caracteres no numericos
  • Campos insertando 0s
  • Campos con numeros muy grandes
  • Campos normales con datos que tienen sentido

History Feature

En este feature se hicieron pruebas sobre la vista de History. Se probaron escenarios donde se interactuaba con esta vista en los siguientes casos:

  • Historial en blanco pues no se han agregado registros
  • Historial normal con registros que tienen sentido
  • Historial con registros que tienen valores muy grandes

Statistics Feature

En este feature se hicieron pruebas sobre la vista de Statistics. Se probaron escenarios donde se interactuaba con esta vista en los siguientes casos:

  • Estadísticas en blanco pues no se han agregado registros
  • Estadísticas normales con registros que tienen sentido
  • Estadísticas con registros que tienen valores muy grandes

Vehicle Feature

En este feature se hicieron pruebas sobre la vista de Vehicle. Se probó un escenario donde se listan los vehículos que hay (solo hay 1) y se ingresa a este.

UI Feature

En este feature se hicieron pruebas sobre la interfaz general de la aplicación. Se hizo interacción con los tabs de esta teniendo el dispositivo en ambas orientaciones.

Reducción de features

Una vez se corrieron los escenarios para los features descritos anteriormente. Estos tomaban un tiempo de ejecución muy largo de entre 12 y 14 minutos en la instancia de Google Cloud. Se pudo ver que varios de los escenarios contenían pasos que se ejecutaban en otros escenarios y se tomó la decisión de combinar varios de estos en un solo escenario para agilizar la ejecución de los mismos. Las reducciones que se hicieron fueron las siguientes:

  • Combinar escenarios de History Feature en Fillup Feature
  • Combinar escenarios de Statistics Feature en Fillup Feature

Una vez hecho esto se pudieron eliminar los features History Feature y Statistics Feature. Esto se pudo hacer ya que en los features eliminados se requería inicializar la aplicación insertando registros de tanqueo. Sin embargo, esto también se hace en los escenarios de Fillup Feature y por ende se podían combinar los escenarios de tal forma que se ejecutaban más rápido sin dejar de probar los mismos flujos.

En este enlace se puede ver el código de los features implementados en Calabash.

Permisos

Calabash exige que las aplicaciones tengan permiso a Internet para poder ejecutar las pruebas. Sin embargo esto no ocurre en la aplicación Mileage. Para solucionar esto se realizaron dos scripts que agregaron este permiso sobre todos los mutantes de la siguiente forma:

Script 1

El primer script se encargaba de agregar el permiso a Internet siguiendo estos pasos sobre cada mutante:

  • Decompilar el archivo .apk del mutante usando la utilidad Apktool
  • Modificar el archivo AndroidManifest.xml agregando el permiso de Internet
  • Generar nuevamente el archivo .apk con el AndroidManifest.xml modificado

En este enlace se puede ver el código del script.

Script 2

El segundo script se encargaba de firmar el archivo .apk resultante con una llave de depuración genérica creada para este propósito. En este enlace se puede ver el código del script.

La ejecución de ambos scripts tomó aproximadamente 3 horas. El resultado se subió a GitHub para acceder a este de forma fácil desde la instancia de Google Cloud. El repositorio se puede encontrar aquí.

Mutantes dañados

Mientras corrían los scripts que agregan el permiso a Internet, se encontró que había un mutante dañado, la carpeta del mutante es com.evancharlton.mileage-mutant1520 y se encontró que el archivo .apk no estaba sino en cambio un .apk.filepart. Se decidió eliminar el mutante del proyecto.

Reporte

Los resultados de las pruebas al correrlas sobre cada mutante son:

  • Reporte HTML con información de la ejecución de los flujos
  • Capturas de pantalla tomadas en los flujos
  • Logs extraídos del emulador que corría las pruebas

Reporte HTML

Para obtener este reporte se hizo uso de las opciones --format html y --out report.html que provee Calabash.

Capturas de pantalla

Las capturas de pantalla se tomaban de manera arbitraria durante las pruebas y se guardaban en una carpeta screenshots.

Logs

Para extraer los logs se hizo uso de la utilidad adb logcat limpiando el contenido de estos antes de cada escenario y guardando el estado actual de estos al terminar de correr cada escenario. Para esto se modificó el lifecycle de Calabash en el archivo app_life_cycle_hooks.rb agregando los comandos respectivos.

Automatización

La ejecución de cada mutante requiere una serie de pasos que incluyen limpiar archivos viejos, crear carpetas para guardar logs y capturas de pantalla, correr las pruebas y guardar los resultados en una carpeta específica para cada mutante. Para poder simplificar esto se creo un script que realiza cada uno de los pasos para un mutante dado. La implementación de este script se puede ver en este enlace.

Entorno

La parte que mas tomo tiempo durante el proyecto fue configurar la instancia de Google Cloud. Para esta se instaló ruby 2.3.1 usando el gestor de versiones rvm. De igual manera se instalo Java 8 Oracle. Se copiaron las llaves de seguridad necesarias para acceder a github idpart.ssh y para firmar las aplicaciones debug.keystore. También fue necesario instalar las herramientas de Android SDK desde la página oficial y utilizar el sdkmanager para instalar las herramientas faltantes. Por último se instalaron los paquetes necesarios para la ejecución de la virtualización embebida para así poder correr el emulador.

Ejecución

Paralelización

Una vez se tuvieron las pruebas de Calabash listas se pudo notar que su ejecución era demasiado lenta. En la instancia de Google Cloud que se mencionó en la estrategia de pruebas duraba entre 6 y 8 minutos la ejecución de las pruebas sobre cada mutante incluso después de haber hecho la reducción mencionada antes. Esto multiplicado por el número de mutantes da un tiempo total de aproximadamente 175 horas. Con el fin de incrementar la velocidad de ejecución de las pruebas se crearon múltiples instancias de Google Cloud y se distribuyó el trabajo entre estas. Especificamente se usaron 93 instancias donde cada una procesaba 16 mutantes diferentes. El resultado de todos los mutantes se subió a un repositorio común por cada una de las instancias. Cabe mencionar que cada una de las instancias es idéntica a las otras y tienen las especificaciones que se mencionan en la estrategia de pruebas.

Trabajo entre instancias

Automatización

Con el fin de ejecutar rápidamente las instrucciones requeridas para correr las pruebas sobre un conjunto de mutantes y publicar los resultados a un repositorio, se hicieron dos script que automatiza este trabajo. Para llevar un monitoreo del estado de cada instancia se escribió en un archivo el último mutante procesado.

Script 1

Este script se encarga de correr las pruebas sobre una lista de mutantes dada como archivo de entrada. Cabe aclarar que previamente se dividió la lista de 1500 mutantes en archivos de 16 mutantes. Una vez se corren todas las pruebas este script llama al script 2 para publicar los resultados que se generaron. La implementación de este script se puede ver en este enlace.

Script 2

Este script se encarga de publicar los resultados de todos los mutantes sobre los cuales se ejecutaron las pruebas. La forma en que lo hace es subiendo los resultados a Github en su propio branch dado un repositorio común results. La implementación de este script se puede ver en este enlace.

Repositorio resultados

Como se mencionó antes, los resultados se subieron a un repositorio común al cual cada instancia tiene acceso. Para evitar condiciones de carrera al momento de subir los resultados se usó una rama por cada instancia. El repositorio de los resultados se puede ver en este enlace.

Una vez se tuvieron todos los branch con resultados fue posible hacer merge de todos estos en el branch master con el fin de unificarlos y analizarlos.

Instrucciones remotas

Ya que se creó un número considerable de instancias de Google Cloud, se hicieron distintos scripts para poder ejecutar comandos al mismo tiempo a través de SSH. A continuación se describen estos scripts:

Script 1

Este script se encarga de crear una imagen de disco identica a la imagen base. La imagen base contiene todo lo necesario para correr las pruebas incluyendo lo que se describió en la sección de entorno y todos los repositorios del proyecto. La implementación de este script se encuentra en este enlace.

Script 2

Este script se encarga de crear una instancia para cada una de las imágenes que se crearon usando el script anterior. La implementación de este script se encuentra en este enlace.

Script 3

Este script se encarga de correr el comando git pull origin master sobre el repositorio con los scripts que corren las pruebas para mantenerse actualizado con los últimos cambios a estos. La implementación de este script se encuentra en este enlace.

Script 4

Este script se encarga de iniciar el emulador de Android en cada una de las instancias de Google Cloud creadas. La implementación de este script se encuentra en este enlace.

Script 5

Este script se encarga de validar que los emuladores hayan iniciado con éxito en cada una de las instancias de Google Cloud creadas. La implementación de este script se encuentra en este enlace.

Script 6

Este script se encarga de correr las pruebas con el archivo de batch que le corresponde a cada una de las instancias. Es decir, especificando el trabajo que debe realizar cada instancia. La implementación de este script se encuentra en este enlace.

Script 7

Este script se encarga de detener todas las instancias de Google Cloud creadas. La implementación de este script se encuentra en este enlace.

VRT

Teniendo todos los resultados, se hizo en una única máquina VRT de las capturas tomadas en los mutantes contra el baseline.