En Mi Local Funciona

Technical thoughts, stories and ideas

Ejecución de pruebas automatizadas en la granja de dispositivos de Amazon - AWS Device Farm

Publicado por Cristina Lopez-Goicochea Juarez el

QAAppiumAWS Device Farm

En este artículo veremos cómo se prepara un proyecto Maven de automatización de pruebas con la estructura necesaria para ser ejecutado en la granja de dispositivos de Amazon AWS Device Farm. También veremos cómo crear una nueva ejecución en AWS y finalmente cómo muestra AWS el resultado final de la ejecución.

Consideraciones a tener en cuenta. En AWS Device Farm disponemos de una instancia de Appium arrancada en el momento en el que se ejecuta el test, con lo que en el caso de que el proyecto sea susceptible de ser ejecutado fuera del entorno AWS será primordial tenerlo preparado y parametrizado para poder ejecutarse con la instancia de Appium arrancada o sin ella.

Preparación del proyecto de automatización

Disponemos de un proyecto sencillo el cual automatiza una aplicación móvil Android. Esta aplicación contiene una página de login con un usuario y un password. El test consistirá en hacer login con credenciales correctas y verificar que el acceso se ha realizado correctamente.

Este proyecto está ubicado en el repositorio GitHub : https://github.com/cristinalopezgj/aws-appium-cucumber-example

Una vez tenemos los tests codificados, es necesario realizar unas adaptaciones en el proyecto con el fin de poder generar un fichero ZIP cuyo formato deberá ser el requerido para ser utilizando en AWS. Este ZIP deberá contener en la raíz un fichero JAR con los tests y una carpeta llamada "dependency-jars" con la totalidad de las librerías requeridas en la ejecución.

Para hacer la tarea más sencilla, modificaremos el fichero pom.xml del proyecto realizando las siguientes modificaciones:

Añadir la variable skipTests con valor a true en las properties. Con esta variable a true haremos el ensamblaje sin necesidad de ejecutar todos los tests de la aplicación:

<properties>  
    <skipTests>true</skipTests>
    ...
</properties>  

Añadir las dependencias de TestNG:

<dependency>  
    <groupId>org.testng</groupId>
    <artifactId>testng</artifactId>
    <version>6.14.3</version>
    <scope>test</scope>
</dependency>  
<dependency>  
    <groupId>info.cukes</groupId>
    <artifactId>cucumber-testng</artifactId>
    <version>LATEST</version>
    <scope>test</scope>
</dependency>  

Configurar los plugins de Maven de compilación y ensamblaje para la creación del fichero ZIP. El ensamblaje requerirá de un fichero "assembly.xml" adicional:

<build>  
    <plugins>
        <!-- maven-resources-plugin -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-resources-plugin</artifactId>
            <configuration>
                <encoding>${project.reporting.outputEncoding}</encoding>
            </configuration>
        </plugin>
        <!-- maven-surefire-plugin -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>3.0.0-M1</version>
            <configuration>
                <skipTests>${skipTests}</skipTests>
            </configuration>
        </plugin>
        <!-- maven-compiler-plugin -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>${maven.compiler.source}</source>
                <target>${maven.compiler.target}</target>
                <encoding>${project.reporting.outputEncoding}</encoding>
            </configuration>
        </plugin>
        <!-- maven-jar-plugin -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>3.1.0</version>
            <configuration>
                <archive>
                    <manifest>
                        <mainClass>com.appium.stepdefinitions.RunCukeTestNG</mainClass>
                    </manifest>
                </archive>
            </configuration>
            <executions>
                <!-- Generates a jar file only with the test classes -->
                <execution>
                    <goals>
                        <goal>test-jar</goal>
                    </goals>
                    <configuration>
                        <includes>
                            <include>**/**</include>
                        </includes>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <!-- maven-assembly-plugin -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.3</version>
            <configuration>
                <descriptor>assembly.xml</descriptor>
            </configuration>
            <executions>
                <execution>
                    <id>make-assembly</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                    <configuration>
                        <descriptorRefs>
                            <descriptorRef>jar-with-dependencies</descriptorRef>
                        </descriptorRefs>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>  

El fichero assembly.xml, será el encargado de realizar el ensamblaje y creación del ZIP:

<?xml version="1.0" encoding="UTF-8"?>  
<assembly  
        xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
    <id>aws-devicefarm</id>
    <formats>
        <format>zip</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <dependencySets>
        <dependencySet>
            <scope>test</scope>
            <includes>
                <include>*:jar:*</include>
            </includes>
            <outputDirectory>/dependency-jars</outputDirectory>
        </dependencySet>
    </dependencySets>
    <fileSets>
        <fileSet>
            <directory>${project.basedir}/target</directory>
            <outputDirectory>/</outputDirectory>
            <includes>
                <include>*-tests.jar</include>
            </includes>
        </fileSet>
    </fileSets>
</assembly>  

El plugin será ejecutado en la fase "package" de Maven. Con lo que para ejecutarlo completo deberemos ir a la raíz del proyecto e indicar:

mvn clean package  

Una vez finalice el proceso, el directorio target del proyecto deberá tener un aspecto como el siguiente:

Podemos observar como se ha generado el fichero ZIP listo para ser utilizando en AWS. Si lo abrimos vemos la estructura siguiente:

Con estos pasos ya tenemos el proyecto adaptado y con el ZIP creado.

Creación de una nueva ejecución en AWS Device Farm y revisión de resultados

Una vez accedemos a AWS Device Farm, vemos una pantalla como la siguiente:

Creamos un nuevo proyecto o accedemos si ya existe. Dentro de la pestaña "Automated tests", veremos la lista de ejecuciones realizadas con sus respectivos resultados y tiempos de ejecución. Para crear una nueva ejecución, hacemos clic en "Create a new run":

El primer paso será determinar qué tipo de ejecución queremos. Si vamos a ejecutar un test de una aplicación móvil o bien si vamos a ejecutar un test de una aplicación web. Dependiendo de cuál escojamos se nos presentarán unas pantallas u otras.

Si queremos ejecutar una aplicación móvil, veremos una pantalla como la siguiente:

Aquí deberemos hacer upload de nuestra aplicación móvil (Android - APK o bien iOS - IPA). En el caso de haber hecho upload previo podremos seleccionarla en "Select a recent upload".

Una vez subida la aplicación, nos mostrará la información de la misma. Pulsamos Next.

Por el contrario, si queremos ejecutar una aplicación web, saltaremos el paso anterior yendo directamente a la siguiente pantalla:

En esta pantalla seleccionaremos qué tipo de Test queremos ejecutar (JUnit, Python, Node.js, etc). En nuestro caso seleccionaremos Appium Java Unit, aunque AWS necesitará de un fichero testng.xml para poder ejecutar.

Antes de continuar, necesitaremos subir el ZIP generado con el ensamblaje. Para ello hacemos un upload del mismo o bien lo seleccionamos si ya lo hemos subido en una ejecución anterior.

Si el fichero ZIP tuviera algún error de estructura u otro error que imposibilitara la ejecución nos aparecería un error indicando el motivo. En caso contrario, AWS nos mostrará el entorno de ejecución, el fichero YAML correspondiente para ejecutar. Este fichero podemos editarlo y adaptarlo a nuestras necesidades, como por ejemplo si quisiéramos añadir alguna variable de entrada al proyecto, como veremos más adelante.

En el caso de editarlo, nos permitirá guardar un fichero YAML personalizado con nuestra ejecución. Para el caso que nos atañe hemos modificado el YAML incluyendo las lineas de la 67 a la 70, ambas inclusive. Haremos un unzip del fichero JAR de tests incluido dentro del ZIP y en la llamada al test añadimos dos variables que nuestro proceso necesita: -Ddevice=$DEVICEFARMDEVICEUDID y -DappiumON=S. Finalmente indicaremos el fichero testng.xml que AWS necesita para ejecutar.

La primera variable, la obtenemos del propio YAML e identifica el dispositivo donde haremos la emulación del test. El segundo parámetro, tal y como se explica en las consideraciones previas al inicio del documento, especificamos si la instancia de Appium está arrancada o no. Gracias a este parámetro evitaremos tener que modificar el código fuente del proyecto cada vez que queramos ejecutarlo según en qué entorno lo hagamos (AWS o fuera de él). Pulsamos Next.

Seleccionamos el dispositivo donde queremos ejecutar el test. A través de la opción "Create a new device pool" podremos crear nuestra lista personalizada de dispositivos. En el caso de incompatibilidad del SO del dispositivo con la versión de Appium a utilizar en el test, AWS nos avisará. Pulsamos Next:

En la pantalla siguiente podremos especificar condiciones adicionales del dispositivo, tales como conexión WiFi, Bluetooth, localización GPS del dispositivo, etc. En nuestro caso no aplicamos ningún cambio. Este paso solo aplica si estamos ejecutando una aplicación móvil. Pulsamos Next:

En la última pantalla especificamos el tiempo que queremos dedicar al test por dispositivo. En este caso, aplicamos unos 5 minutos de ejecución. Es importante en este paso saber ajustar bien los tiempos para no incurrir en errores de tiemout. Pulsamos "Confirm and start run". El test empezará automáticamente a ejecutarse:

No se podrá visualizar el estado del test durante su ejecución, sino que habrá que esperar a que éste finalice para ver el resultado. Una vez finalice, si ha ido bien, veremos un estado como el siguiente:

Haciendo clic en él, podremos acceder a toda la información de la ejecución:

Hacemos clic en la ejecución de nuevo y accederemos a los logs y video de la ejecución. El vídeo podremos descargarlo como evidencia.

Si observamos los logs, vemos como se ha hecho el unzip de los tests y se ha ejecutado el escenario de Login a través de Cucumber:

Por último, también podremos obtener datos del rendimiento de la ejecución: uso de la CPU, memoria, etc.:

Conclusión

AWS Device Farm es una herramienta muy útil para poder realizar pruebas sobre aplicaciones móviles o aplicaciones web tanto en Android como en iOS, evitando así los costes que supone disponer de una granja de dispositivos propia para realizar las pruebas y la configuración a nivel de máquinas supone montar toda la infraestructura necesaria.

Si te ha gustado, ¡síguenos en Twitter para estar al día de próximos posts!