Implementar, escalar: experiencia en el uso de pruebas automatizadas en VTB

Nuestra división crea canales totalmente automáticos para lanzar nuevas versiones de aplicaciones en el entorno de producción. Por supuesto, esto requiere pruebas funcionales automatizadas. Debajo del corte hay una historia sobre cómo, comenzando con pruebas de un solo subproceso en una máquina local, pasamos a pruebas automáticas de subprocesos múltiples que se ejecutan en Selenoid en el proceso de compilación con un informe de Allure en las páginas de GitLab y finalmente obtuvimos una excelente herramienta de automatización que las personas del futuro podrán utilizar equipos.

Implementar, escalar: experiencia en el uso de pruebas automatizadas en VTB

¿Por dónde empezamos?

Para implementar pruebas automáticas e integrarlas en el proceso, necesitábamos un marco de automatización que pudiera modificarse de manera flexible para satisfacer nuestras necesidades. Idealmente, quería obtener un estándar único para el motor de pruebas automáticas, adaptado para incorporar pruebas automáticas en la tubería. Para su implementación elegimos las siguientes tecnologías:

  • Java
  • experto,
  • Selenio,
  • Pepino+JUNIT 4,
  • ritmo,
  • GitLab.

Implementar, escalar: experiencia en el uso de pruebas automatizadas en VTB

¿Por qué este conjunto en particular? Java es uno de los lenguajes más populares para pruebas automatizadas y todos los miembros del equipo lo hablan. El selenio es la solución obvia. Se suponía que Pepino, entre otras cosas, aumentaría la confianza en los resultados de las pruebas automatizadas por parte de los departamentos involucrados en las pruebas manuales.

Pruebas de un solo hilo

Para no reinventar la rueda, tomamos como base para el marco desarrollos de varios repositorios en GitHub y los adaptamos nosotros mismos. Creamos un repositorio para la biblioteca principal con el núcleo del marco de pruebas automáticas y un repositorio con un ejemplo Gold de implementación de pruebas automáticas en nuestro núcleo. Cada equipo tuvo que tomar la imagen Gold y desarrollar pruebas en ella, adaptándola a su proyecto. Lo implementamos en el banco GitLab-CI, en el que configuramos:

  • ejecuciones diarias de todas las pruebas automáticas escritas para cada proyecto;
  • lanzamientos en el proceso de construcción.

Al principio hubo pocas pruebas y se llevaron a cabo en una sola secuencia. La ejecución de un solo subproceso en el corredor de Windows GitLab nos vino bastante bien: las pruebas cargaron el banco de pruebas muy ligeramente y casi no utilizaron recursos.

Con el tiempo, el número de pruebas automáticas se hizo cada vez mayor y pensamos en ejecutarlas en paralelo, cuando una ejecución completa empezó a tardar unas tres horas. También aparecieron otros problemas:

  • no pudimos verificar que las pruebas fueran estables;
  • Las pruebas que se ejecutaron varias veces seguidas en la máquina local a veces fallaban en CI.

Ejemplo de configuración de pruebas automáticas:

<plugins>
	
<plugin>
    	
<groupId>org.apache.maven.plugins</groupId>
    	
<artifactId>maven-surefire-plugin</artifactId>
    	
<version>2.20</version>
    	
<configuration>
        	
<skipTests>${skipTests}</skipTests>
        	
<testFailureIgnore>false</testFailureIgnore>
        	
<argLine>
            	
-javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar"
            	
-Dcucumber.options="--tags ${TAGS} --plugin io.qameta.allure.cucumber2jvm.AllureCucumber2Jvm --plugin pretty"
        	
</argLine>
    	
</configuration>
	
    <dependencies>
        	
<dependency>
            	
<groupId>org.aspectj</groupId>
            	
<artifactId>aspectjweaver</artifactId>
            	
<version>${aspectj.version}</version>
        	
</dependency>
    	
</dependencies>
	
</plugin>
	
<plugin>
    	
<groupId>io.qameta.allure</groupId>
    	
<artifactId>allure-maven</artifactId>
    	
<version>2.9</version>
	
</plugin>
</plugins>

 Implementar, escalar: experiencia en el uso de pruebas automatizadas en VTB
Ejemplo de informe de atracción

 Implementar, escalar: experiencia en el uso de pruebas automatizadas en VTB
Carga del corredor durante las pruebas (8 núcleos, 8 GB de RAM, 1 subproceso)
 
Ventajas de las pruebas de un solo subproceso:

  • fácil de configurar y ejecutar;
  • los lanzamientos en CI prácticamente no se diferencian de los lanzamientos locales;
  • las pruebas no se afectan entre sí;
  • Requisitos mínimos para los recursos del corredor.

Desventajas de las pruebas de un solo subproceso:

  • tomará mucho tiempo completarlo;
  • larga estabilización de pruebas;
  • Uso ineficiente de los recursos del corredor, utilización extremadamente baja.

Pruebas en bifurcaciones JVM

Dado que no nos ocupamos del código seguro para subprocesos al implementar el marco base, la forma más obvia de ejecutarlo en paralelo fue complemento-paralelo-jvm-pepino para Maven. El complemento es fácil de configurar, pero para un funcionamiento paralelo correcto, las pruebas automáticas deben ejecutarse en navegadores separados. No hay nada que hacer, tuve que usar Selenoid.

El servidor Selenoid se lanzó en una máquina con 32 núcleos y 24 GB de RAM. El límite se fijó en 48 navegadores: 1,5 subprocesos por núcleo y unos 400 MB de RAM. Como resultado, el tiempo de prueba se redujo de tres horas a 40 minutos. Acelerar las ejecuciones ayudó a resolver el problema de estabilización: ahora podíamos ejecutar rápidamente nuevas pruebas automáticas entre 20 y 30 veces hasta que estuviéramos seguros de que se ejecutaban de manera confiable.
El primer inconveniente de la solución fue la alta utilización de recursos del corredor con una pequeña cantidad de subprocesos paralelos: en 4 núcleos y 8 GB de RAM, las pruebas se ejecutaron de manera estable en no más de 6 subprocesos. La segunda desventaja: el complemento genera clases de corredor para cada escenario, sin importar cuántos de ellos se lancen.

¡Importante! No pase una variable con etiquetas a líneaarg, por ejemplo, así:

<argLine>-Dcucumber.options="--tags ${TAGS} --plugin io.qameta.allure.cucumber2jvm.AllureCucumber2Jvm --plugin pretty"</argLine>
…
Mvn –DTAGS="@smoke"

Si pasa la etiqueta de esta manera, el complemento generará ejecutores para todas las pruebas, es decir, intentará ejecutar todas las pruebas, omitiéndolas inmediatamente después del lanzamiento y creando muchas bifurcaciones JVM.

Es correcto lanzar una variable con una etiqueta en etiquetas en la configuración del complemento, vea el ejemplo a continuación. Otros métodos que probamos tienen problemas para conectar el complemento Allure.

Ejemplo de tiempo de ejecución para 6 pruebas cortas con configuraciones incorrectas:

[INFO] Total time: 03:17 min

Ejemplo de tiempo de ejecución de prueba si transfiere directamente la etiqueta a mvn... –Dcucumber.opciones:

[INFO] Total time: 44.467 s

Ejemplo de configuración de pruebas automáticas:

<profiles>
	
<profile>
    	
<id>parallel</id>
    	
<build>
        	
<plugins>
            	
<plugin>
                	
<groupId>com.github.temyers</groupId>
                	
<artifactId>cucumber-jvm-parallel-plugin</artifactId>
                	
<version>5.0.0</version>
                	
<executions>
                    	
<execution>
                        	
<id>generateRunners</id>
                        	
<phase>generate-test-sources</phase>
                        	
<goals>
                            	
<goal>generateRunners</goal>
                        	
</goals>
                        	
<configuration>
                	
            <tags>
                            	
<tag>${TAGS}</tag>
                            	
</tags>
                            	
<glue>
                                	
<package>stepdefs</package>
                            	
</glue>
                        	
</configuration>
     	
               </execution>
                	
</executions>
    	
        </plugin>
            	
<plugin>
                	
<groupId>org.apache.maven.plugins</groupId>
                	
<artifactId>maven-surefire-plugin</artifactId>
        	
        <version>2.21.0</version>
                	
<configuration>
                    	
<forkCount>12</forkCount>
                    	
<reuseForks>false</reuseForks>
                    	
<includes>**/*IT.class</includes>
                   	
 <testFailureIgnore>false</testFailureIgnore>
                    	
<!--suppress UnresolvedMavenProperty -->
                    	
<argLine>
  	
 -javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar" -Dcucumber.options="--plugin io.qameta.allure.cucumber2jvm.AllureCucumber2Jvm TagPFAllureReporter --plugin pretty"
                    	
</argLine>
                	
</configuration>
                	
<dependencies>
                    	
<dependency>
                        	
<groupId>org.aspectj</groupId>
                        	
<artifactId>aspectjweaver</artifactId>
                        	
<version>${aspectj.version}</version>
                 	
   </dependency>
                	
</dependencies>
         	
   </plugin>
        	
</plugins>
    	
</build>
	
</profile>

Implementar, escalar: experiencia en el uso de pruebas automatizadas en VTB
Ejemplo de informe Allure (la prueba más inestable, 4 repeticiones)

Implementar, escalar: experiencia en el uso de pruebas automatizadas en VTBCarga del corredor durante las pruebas (8 núcleos, 8 GB de RAM, 12 subprocesos)
 
Pros:

  • configuración sencilla: solo necesita agregar un complemento;
  • la capacidad de realizar simultáneamente una gran cantidad de pruebas;
  • aceleración de la estabilización de la prueba gracias al paso 1. 

Contras:

  • Se requieren múltiples SO/contenedores;
  • alto consumo de recursos por cada bifurcación;
  • El complemento está desactualizado y ya no es compatible. 

Cómo superar la inestabilidad 

Los bancos de pruebas no son ideales, al igual que los propios autotests. No es sorprendente que tengamos una serie de pruebas deficientes. vino al rescate complemento seguro de maven, que de fábrica admite el reinicio de pruebas fallidas. Debe actualizar la versión del complemento al menos a 2.21 y escribir una línea con el número de reinicios en el archivo pom o pasarlo como argumento a Maven.

Ejemplo de configuración de pruebas automáticas:

   	
<plugin>
        	
<groupId>org.apache.maven.plugins</groupId>
  	
      <artifactId>maven-surefire-plugin</artifactId>
        	
<version>2.21.0</version>
        	
<configuration>
           	
….
            	
<rerunFailingTestsCount>2</rerunFailingTestsCount>
            	
….
            	
</configuration>
</plugin>

O al inicio: mvn... -Dsurefire.rerunFailingTestsCount=2...
Como opción, configure las opciones de Maven para el script de PowerShell (PS1):

  
Set-Item Env:MAVEN_OPTS "-Dfile.encoding=UTF-8 -Dsurefire.rerunFailingTestsCount=2"

Pros:

  • no es necesario perder el tiempo analizando una prueba inestable cuando falla;
  • Se pueden mitigar los problemas de estabilidad del banco de pruebas.

Contras:

  • se pueden pasar por alto los defectos flotantes;
  • el tiempo de ejecución aumenta.

Pruebas paralelas con la biblioteca Cucumber 4

El número de pruebas crecía cada día. Nuevamente pensamos en acelerar las carreras. Además, quería integrar tantas pruebas como fuera posible en el proceso de ensamblaje de la aplicación. El factor crítico fue que la generación de corredores tomó demasiado tiempo cuando se corría en paralelo usando el complemento Maven.

En ese momento, Cucumber 4 ya había sido lanzado, por lo que decidimos reescribir el kernel para esta versión. En las notas de la versión se nos prometió un lanzamiento paralelo a nivel de hilo. Teóricamente debería tener:

  • acelerar significativamente la ejecución de pruebas automáticas aumentando el número de subprocesos;
  • eliminar la pérdida de tiempo en la generación de corredores para cada autotest.

Optimizar el marco para pruebas automáticas de subprocesos múltiples no resultó ser tan difícil. Cucumber 4 ejecuta cada prueba individual en un hilo dedicado de principio a fin, por lo que algunas cosas estáticas comunes simplemente se convirtieron en variables ThreadLocal. 
Lo principal al realizar una conversión utilizando las herramientas de refactorización de Idea es verificar los lugares donde se comparó la variable (por ejemplo, verificar si hay nulos). Además, debe agregar el complemento Allure a la anotación de clase Junit Runner.

Ejemplo de configuración de pruebas automáticas:

 
<profile>
	
<id>parallel</id>
	
<build>
    	
<plugins>
        	
<plugin>
            	
<groupId>org.apache.maven.plugins</groupId>
 	
           <artifactId>maven-surefire-plugin</artifactId>
            	
<version>3.0.0-M3</version>
   	
         <configuration>
                	
<useFile>false</useFile>
                	
<testFailureIgnore>false</testFailureIgnore>
        	
        <parallel>methods</parallel>
                	
<threadCount>6</threadCount>
                	
<perCoreThreadCount>true</perCoreThreadCount>
                	
<argLine>
                    	
-javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar"
                	
</argLine>
            	
</configuration>
            	
<dependencies>
                	
<dependency>
                    	
<groupId>org.aspectj</groupId>
   	
                 <artifactId>aspectjweaver</artifactId>
                    	
<version>${aspectj.version}</version>
                	
</dependency>
            	
</dependencies>
        	
</plugin>
    	
</plugins>
	
</build>
</profile>

Implementar, escalar: experiencia en el uso de pruebas automatizadas en VTBEjemplo de informe Allure (la prueba más inestable, 5 repeticiones)

Implementar, escalar: experiencia en el uso de pruebas automatizadas en VTBCarga del corredor durante las pruebas (8 núcleos, 8 GB de RAM, 24 subprocesos)

Pros:

  • bajo consumo de recursos;
  • soporte nativo de Cucumber: no se requieren herramientas adicionales;
  • la capacidad de ejecutar más de 6 subprocesos por núcleo de procesador.

Contras:

  • debe asegurarse de que el código admita la ejecución de subprocesos múltiples;
  • el umbral de entrada aumenta.

Informes de Allure en páginas de GitLab

Después de introducir la ejecución multiproceso, comenzamos a dedicar mucho más tiempo a analizar informes. En ese momento, teníamos que cargar cada informe como un artefacto en GitLab, luego descargarlo y descomprimirlo. No es muy cómodo y lleva mucho tiempo. Y si alguien más quiere ver el informe por sí mismo, deberá realizar las mismas operaciones. Queríamos recibir comentarios más rápido y encontramos una solución: las páginas de GitLab. Esta es una característica incorporada que está disponible de fábrica en todas las versiones recientes de GitLab. Le permite implementar sitios estáticos en su servidor y acceder a ellos a través de un enlace directo.

Todas las capturas de pantalla de los informes de Allure se tomaron en las páginas de GitLab. Script para implementar el informe en las páginas de GitLab, en Windows PowerShell (antes de esto, debe ejecutar pruebas automáticas):

New-Item -ItemType directory -Path $testresulthistory | Out-Null

try {Invoke-WebRequest -Uri $hst -OutFile $outputhst}
Catch{echo "fail copy history"}
try {Invoke-WebRequest -Uri $hsttrend -OutFile $outputhsttrnd}
Catch{echo "fail copy history trend"}

mvn allure:report
#mvn assembly:single -PzipAllureReport
xcopy $buildlocationtargetsiteallure-maven-plugin* $buildlocationpublic /s /i /Y

Con el resultado de que 

Entonces, si estaba pensando si necesita código seguro para subprocesos en el marco de prueba automática de Cucumber, ahora la respuesta es obvia: con Cucumber 4 es fácil de implementar, lo que aumenta significativamente la cantidad de subprocesos iniciados simultáneamente. Con este método de ejecución de pruebas, la pregunta ahora es sobre el rendimiento de la máquina con Selenoid y el banco de pruebas.

La práctica ha demostrado que ejecutar pruebas automáticas en subprocesos le permite reducir el consumo de recursos al mínimo con el mejor rendimiento. Como puede verse en los gráficos, duplicar los subprocesos no conduce a una aceleración similar en las pruebas de rendimiento. Sin embargo, pudimos agregar más de 2 pruebas automatizadas a la compilación de la aplicación, que incluso con 200 reejecuciones se ejecutan en aproximadamente 5 minutos. Esto le permite recibir comentarios rápidos de ellos y, si es necesario, realizar cambios y repetir el procedimiento nuevamente.

Fuente: habr.com

Añadir un comentario