Mettre en œuvre, évoluer: l'expérience de l'utilisation des autotests dans VTB

Notre division crée des pipelines entièrement automatiques pour la sortie de nouvelles versions d'applications vers l'environnement de production. Bien sûr, cela nécessite des tests fonctionnels automatisés. Under the cut - l'histoire de la façon dont, en commençant par les tests dans un thread sur la machine locale, nous sommes arrivés au lancement multithread des autotests sur Selenoid dans le pipeline d'assemblage avec le rapport Allure sur les pages GitLab et, par conséquent, nous avons obtenu un outil d'automatisation cool que les futurs pourront utiliser équipes.



Par où avons-nous commencé


Pour implémenter les autotests et les intégrer dans un pipeline, nous avions besoin d'un cadre d'automatisation, qui peut être modifié de manière flexible pour répondre à nos besoins. Idéalement, je voulais obtenir un standard unique pour le moteur d'autotest, adapté pour intégrer des autotests dans un pipeline. Pour la mise en œuvre, nous avons choisi les technologies suivantes:

  • Java
  • Maven
  • Sélénium
  • Concombre + JUNIT 4,
  • Allure
  • Gitlab



Pourquoi un tel ensemble? Java est l'un des langages les plus populaires pour les autotests, de plus, tous les membres de l'équipe le parlent. Le sélénium est la solution évidente. Le concombre, entre autres, était censé accroître la confiance dans les résultats des autotests des unités impliquées dans les tests manuels.

Tests à filetage unique


Afin de ne pas réinventer la roue, nous avons pris les développements de différents référentiels sur GitHub comme base du framework et les avons adaptés pour nous-mêmes. Nous avons créé un référentiel pour la bibliothèque principale avec le cœur du framework d'autotest et un référentiel avec un exemple Gold d'implémentation d'autotests sur notre cœur. Chaque équipe a dû prendre une image Gold et y développer des tests, en l'adaptant à son projet. Nous avons déployé sur la banque GitLab-CI, sur laquelle nous avons configuré:

  • exécutions quotidiennes de tous les autotests écrits pour chaque projet;
  • se lance dans le pipeline d'assemblage.

Au début, il y avait peu de tests, et ils sont allés en un seul flux. Le lancement monothread du GitLab Windows-runner a été assez satisfaisant pour nous: les tests ont très légèrement chargé le banc de test et n'ont presque pas utilisé de ressources.

Au fil du temps, les autotests sont devenus de plus en plus nombreux, et nous avons pensé à les exécuter en parallèle, lorsqu'un cycle complet a commencé à prendre environ trois heures. Il y avait d'autres problèmes:

  • nous n'avons pas pu nous assurer que les tests sont stables;
  • les tests qui ont été exécutés plusieurs fois de suite sur la machine locale tombaient parfois en CI.

Exemple de configuration de l'autotest:

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


Exemple de rapport Allure


Charge du coureur pendant les tests (8 cœurs, 8 Go de RAM, 1 thread)

Avantages des tests monothread:

  • facile à configurer et à exécuter;
  • Les lancements en CI ne diffèrent pratiquement pas des lancements locaux;
  • les tests ne s'influencent pas mutuellement;
  • exigences minimales de ressources de coureur.

Inconvénients des tests monothread:

  • très long terme;
  • longue stabilisation des tests;
  • utilisation inefficace des ressources des coureurs, utilisation extrêmement faible.

Tests de fourche JVM


Comme nous ne nous soucions pas du code thread-safe lors de l'implémentation du framework de base, le plugin cucumber-jvm-parallel-plugin pour Maven est devenu le moyen le plus évident de fonctionner en parallèle. Le plugin est facile à configurer, mais pour le bon fonctionnement parallèle des autotests, vous devez exécuter dans des navigateurs distincts. Rien à faire, j'ai dû utiliser Selenoid.

Le serveur Selenoid a été installé sur une machine avec 32 cœurs et 24 Go de RAM. La limite a été fixée dans 48 navigateurs - 1,5 threads par cœur et environ 400 Mo de RAM. En conséquence, la durée du test a été réduite de trois heures à 40 minutes. L'accélération des analyses a aidé à résoudre le problème de stabilisation: nous pouvons désormais exécuter rapidement de nouveaux autotests 20 à 30 fois jusqu'à ce que nous nous assurions qu'ils sont effectués de manière stable.
Le premier inconvénient de la solution était la forte utilisation des ressources du runner avec un petit nombre de threads parallèles: sur 4 cœurs et 8 Go de RAM, les tests fonctionnaient de manière stable dans pas plus de 6 threads. Le deuxième inconvénient: le plugin génère des classes de coureurs pour chaque scénario, quel que soit le nombre exécuté.

Important! Ne lancez pas une variable avec des balises dans argLine , par exemple, comme ceci:

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

Si vous passez la balise de cette façon, le plugin générera des coureurs pour tous les tests, c'est-à-dire, essayez d'exécuter tous les tests, en les sautant juste après le lancement et en créant beaucoup de fourches JVM.

Il est correct de jeter la variable avec la balise dans des balises dans les paramètres du plug-in, voir l'exemple ci-dessous. D'autres méthodes que nous avons testées ont des problèmes pour connecter le plugin Allure.

Exemple de durée d'exécution pour 6 tests courts avec des paramètres incorrects:

 [INFO] Total time: 03:17 min 

Un exemple d'exécution de test si vous passez directement la balise à mvn ... –Dcucumber.options :

 [INFO] Total time: 44.467 s 

Exemple de configuration de l'autotest:

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


Un exemple de rapport Allure (le test le plus instable, 4 rerana)

Charge du coureur pendant les tests (8 cœurs, 8 Go de RAM, 12 threads)

Avantages:

  • configuration simple - il vous suffit d'ajouter le plugin;
  • la capacité d'effectuer simultanément un grand nombre de tests;
  • stabilisation plus rapide des tests grâce à la revendication 1.

Inconvénients:

  • plusieurs OS / conteneurs requis;
  • consommation élevée de ressources par fourchette;
  • Le plugin est obsolète et n'est plus pris en charge.

Comment vaincre l'instabilité


Les bancs d'essai ne sont pas parfaits, tout comme les tests automatiques eux-mêmes. Sans surprise, nous avons obtenu un certain nombre de tests louches. Le plugin maven surefire est venu à la rescousse , qui, dès la sortie de la boîte, prend en charge le redémarrage des tests tombés. Vous devez mettre à jour la version du plugin à au moins 2.21 et écrire une ligne avec le nombre de redémarrages dans le fichier pom ou passer comme argument pour Maven.

Exemple de configuration de l'autotest:

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

Ou au démarrage: mvn ... -Dsurefire.rerunFailingTestsCount = 2 ...
Vous pouvez également définir les options Maven pour le script PowerShell (PS1):

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

Avantages:

  • pas besoin de perdre du temps à analyser un test instable lorsqu'il se bloque;
  • Vous pouvez atténuer les problèmes de stabilité du banc d'essai.

Inconvénients:

  • vous pouvez ignorer les défauts flottants;
  • le temps d'exécution est augmenté.

Tests parallèles avec la bibliothèque Cucumber 4



Le nombre de tests augmente chaque jour. Nous avons pensé à nouveau à accélérer les pistes. De plus, je souhaitais intégrer autant de tests que possible dans l'assemblage pipeline de l'application. Un facteur critique était la génération trop longue de coureurs lors de l'exécution en parallèle à l'aide du plugin Maven.

Cucumber 4 était déjà sorti à cette époque, nous avons donc décidé de réécrire le noyau pour cette version. Dans les notes de version, on nous avait promis un lancement parallèle au niveau du thread. Théoriquement, cela aurait dû être:

  • accélérer considérablement l'exécution des autotests en augmentant le nombre de threads;
  • exclut la perte de temps pour générer des coureurs pour chaque autotest.

L'optimisation du cadre pour les autotests multithread n'était pas si difficile. Cucumber 4 exécute chaque test individuel dans un thread dédié du début à la fin, donc certaines choses statiques courantes ont été simplement converties en variables ThreadLocal.
La chose principale lors de la conversion avec les outils de refactoring Idea est de vérifier les endroits où la variable a été comparée (par exemple, vérifier la valeur null). De plus, vous devez rendre le plugin Allure dans les annotations de la classe Junit Runner.

Exemple de configuration de l'autotest:

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

Un exemple de rapport Allure (le test le plus instable, 5 répétitions)

Charge du coureur pendant les tests (8 cœurs, 8 Go de RAM, 24 threads)

Avantages:

  • faible consommation de ressources;
  • support natif de Cucumber - aucun outil supplémentaire requis;
  • la possibilité d'exécuter plus de 6 threads sur le cœur du processeur.

Inconvénients:

  • vous devez vous assurer que le code prend en charge l'exécution multithread;
  • le seuil d'entrée augmente.

Rapports Allure dans les pages GitLab


Après l'introduction du lancement multithread, nous avons commencé à consacrer beaucoup plus de temps à l'analyse des rapports. À cette époque, nous devions télécharger chaque rapport comme un artefact dans GitLab, puis le télécharger, le décompresser. Ce n'est pas très pratique et long. Et si quelqu'un d'autre veut voir le rapport à la maison, alors il devra faire les mêmes opérations. Nous voulions obtenir des commentaires plus rapidement, et il y avait un moyen de sortir - les pages GitLab. Il s'agit d'une fonctionnalité intégrée qui est disponible dès le départ dans toutes les versions récentes de GitLab. Vous permet de déployer des sites statiques sur votre serveur et d'y accéder via un lien direct.

Toutes les captures d'écran avec les rapports Allure ont été réalisées dans les pages GitLab. Le script de déploiement du rapport sur les pages GitLab est destiné à Windows PowerShell (avant cela, vous devez exécuter les autotests):

 New-Item -ItemType directory -Path $testresult\history | 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 $buildlocation\target\site\allure-maven-plugin\* $buildlocation\public /s /i /Y 

Quel est le résultat


Donc, si vous vous demandiez si vous avez besoin d'un code Thread safe dans le cadre de l'autotest Cucumber, la réponse est maintenant évidente - avec Cucumber 4, il est facile à implémenter, augmentant ainsi considérablement le nombre de threads lancés simultanément. Avec cette méthode d'exécution des tests, la question porte déjà sur les performances de la machine avec Selenoid et le banc d'essai.

La pratique a montré que l'exécution d'autotests sur les threads peut minimiser la consommation de ressources avec les meilleures performances. Comme on peut le voir sur les graphiques, une augmentation du double des débits ne conduit pas à une accélération similaire lors des tests de performances réussis. Néanmoins, nous avons été en mesure d'ajouter plus de 200 tests automatiques à l'ensemble d'application, qui, même avec 5 reprises, peuvent être effectués en environ 24 minutes. Cela vous permet de recevoir rapidement des commentaires de leur part et, si nécessaire, d'apporter des modifications et de répéter la procédure à nouveau.

Source: https://habr.com/ru/post/fr473950/


All Articles