Implementeren, opschalen: ervaring met het gebruik van geautomatiseerde tests bij VTB

Onze divisie creëert volledig automatische pijplijnen voor het lanceren van nieuwe versies van applicaties in de productieomgeving. Uiteraard vereist dit geautomatiseerde functionele tests. Hieronder staat een verhaal over hoe we, beginnend met single-thread testen op een lokale machine, het punt bereikten van multi-threaded autotest op Selenoid in de build-pijplijn met een Allure-rapport op GitLab-pagina's en uiteindelijk een coole automatiseringstool kregen dat toekomstige mensen teams kunnen gebruiken.

Implementeren, opschalen: ervaring met het gebruik van geautomatiseerde tests bij VTB

Waar zijn we begonnen?

Om autotests te implementeren en in de pijplijn te integreren, hadden we een automatiseringsframework nodig dat flexibel kon worden aangepast aan onze behoeften. Idealiter wilde ik één enkele standaard krijgen voor de autotest-engine, aangepast om autotests in de pijplijn te integreren. Voor de implementatie hebben we gekozen voor de volgende technologieën:

  • Java
  • Maven,
  • Selenium,
  • Komkommer+JUNIT 4,
  • Verleiden,
  • GitLab.

Implementeren, opschalen: ervaring met het gebruik van geautomatiseerde tests bij VTB

Waarom deze specifieke set? Java is een van de populairste talen voor geautomatiseerde tests en alle teamleden spreken het. Selenium is de voor de hand liggende oplossing. Komkommer moest onder meer het vertrouwen in de resultaten van geautomatiseerde tests vergroten bij afdelingen die zich bezighouden met handmatige tests.

Testen met enkele schroefdraad

Om het wiel niet opnieuw uit te vinden, hebben we ontwikkelingen uit verschillende repositories op GitHub als basis voor het framework genomen en voor onszelf aangepast. We hebben een repository gemaakt voor de hoofdbibliotheek met de kern van het autotest-framework en een repository met een Gold-voorbeeld van het implementeren van autotests op onze core. Elk team moest het Gold-imago nemen en er tests in ontwikkelen, en deze aanpassen aan hun project. We hebben het geïmplementeerd in de GitLab-CI-bank, waarop we het volgende hebben geconfigureerd:

  • dagelijkse uitvoering van alle geschreven autotests voor elk project;
  • wordt gelanceerd in de build-pijplijn.

In eerste instantie waren er weinig tests en werden ze in één stroom uitgevoerd. Single-threaded draaien op de Windows runner GitLab beviel ons redelijk goed: de tests belastten de testbank heel licht en gebruikten bijna geen bronnen.

In de loop van de tijd werd het aantal autotests steeds talrijker en we dachten erover om ze parallel uit te voeren, toen een volledige run ongeveer drie uur begon te duren. Er deden zich ook andere problemen voor:

  • we konden niet verifiëren dat de tests stabiel waren;
  • tests die meerdere keren achter elkaar op de lokale machine werden uitgevoerd, crashten soms in CI.

Voorbeeld van het instellen van autotests:

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

 Implementeren, opschalen: ervaring met het gebruik van geautomatiseerde tests bij VTB
Voorbeeld van een Allure-rapport

 Implementeren, opschalen: ervaring met het gebruik van geautomatiseerde tests bij VTB
Runnerbelasting tijdens tests (8 cores, 8 GB RAM, 1 thread)
 
Voordelen van tests met één thread:

  • eenvoudig in te stellen en uit te voeren;
  • lanceringen in CI verschillen praktisch niet van lokale lanceringen;
  • tests hebben geen invloed op elkaar;
  • minimumvereisten voor middelen voor hardlopers.

Nadelen van tests met één schroefdraad:

  • het duurt erg lang om het te voltooien;
  • lange stabilisatie van tests;
  • inefficiënt gebruik van runner-bronnen, extreem laag gebruik.

Tests op JVM-vorken

Omdat we bij de implementatie van het basisframework geen zorg hebben gedragen voor thread-safe code, was de meest voor de hand liggende manier om parallel te draaien komkommer-jvm-parallel-plug-in voor Maven. De plug-in is eenvoudig te configureren, maar voor een correcte parallelle werking moeten autotests in aparte browsers worden uitgevoerd. Er is niets te doen, ik moest Selenoid gebruiken.

De Selenoid-server werd gelanceerd op een machine met 32 ​​cores en 24 GB RAM. De limiet was vastgesteld op 48 browsers - 1,5 threads per core en ongeveer 400 MB RAM. Als resultaat werd de testtijd teruggebracht van drie uur naar 40 minuten. Het versnellen van de runs hielp het stabilisatieprobleem op te lossen: nu konden we snel twintig tot dertig keer nieuwe autotests uitvoeren totdat we er zeker van waren dat ze betrouwbaar werkten.
Het eerste nadeel van de oplossing was het hoge gebruik van runner-bronnen met een klein aantal parallelle threads: op 4 cores en 8 GB RAM draaiden de tests stabiel in niet meer dan 6 threads. Het tweede nadeel: de plug-in genereert runner-klassen voor elk scenario, ongeacht hoeveel ervan worden gelanceerd.

Belangrijk! Geef geen variabele met tags door argLijnbijvoorbeeld als volgt:

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

Als u de tag op deze manier doorgeeft, genereert de plug-in runners voor alle tests, dat wil zeggen dat hij probeert alle tests uit te voeren, deze onmiddellijk na de lancering over te slaan en veel JVM-vorken te maken.

Het is correct om een ​​variabele met een tag erin te gooien labels in de plugin-instellingen, zie onderstaand voorbeeld. Andere methoden die we hebben getest, hebben problemen met het verbinden van de Allure-plug-in.

Voorbeeld van looptijd voor 6 korte tests met onjuiste instellingen:

[INFO] Total time: 03:17 min

Voorbeeld van testruntijd als u de tag rechtstreeks naar overzet mvn... –Dcucumber.opties:

[INFO] Total time: 44.467 s

Voorbeeld van het instellen van autotests:

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

Implementeren, opschalen: ervaring met het gebruik van geautomatiseerde tests bij VTB
Voorbeeld van een Allure-rapport (de meest onstabiele test, 4 herhalingen)

Implementeren, opschalen: ervaring met het gebruik van geautomatiseerde tests bij VTBRunnerbelasting tijdens tests (8 cores, 8 GB RAM, 12 threads)
 
Voors:

  • eenvoudige installatie - u hoeft alleen maar een plug-in toe te voegen;
  • het vermogen om tegelijkertijd een groot aantal tests uit te voeren;
  • versnelling van de teststabilisatie dankzij stap 1. 

Tegens:

  • Meerdere besturingssystemen/containers vereist;
  • hoog hulpbronnenverbruik voor elke vork;
  • De plug-in is verouderd en wordt niet langer ondersteund. 

Hoe instabiliteit te overwinnen 

Testbanken zijn niet ideaal, net als de autotests zelf. Het is niet verrassend dat we een aantal zwakke tests hebben. Kwam te hulp maven trefzekere plug-in, die standaard het opnieuw starten van mislukte tests ondersteunt. U moet de plug-inversie bijwerken naar minimaal 2.21 en één regel schrijven met het aantal herstarts in het pom-bestand of dit als argument doorgeven aan Maven.

Voorbeeld van het instellen van autotests:

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

Of bij het opstarten: mvn … -Dsurefire.rerunFailingTestsCount=2 …
Stel als optie Maven-opties in voor het PowerShell-script (PS1):

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

Voors:

  • u hoeft geen tijd te verspillen aan het analyseren van een onstabiele test wanneer deze crasht;
  • Stabiliteitsproblemen op de testbank kunnen worden beperkt.

Tegens:

  • drijvende defecten kunnen worden gemist;
  • looptijd neemt toe.

Parallelle tests met de Cucumber 4-bibliotheek

Het aantal tests groeide elke dag. We hebben er opnieuw over nagedacht om de runs te versnellen. Daarnaast wilde ik zoveel mogelijk tests integreren in de applicatie-assemblagepijplijn. De kritische factor was dat het genereren van hardlopers te lang duurde bij parallel draaien met behulp van de Maven-plug-in.

Op dat moment was Cucumber 4 al uitgebracht, dus besloten we de kernel voor deze versie te herschrijven. In de release notes werd ons een parallelle lancering op threadniveau beloofd. Theoretisch zou dit moeten zijn:

  • de uitvoering van autotests aanzienlijk versnellen door het aantal threads te vergroten;
  • elimineer het tijdverlies bij het genereren van runners voor elke autotest.

Het optimaliseren van het raamwerk voor multi-threaded autotests bleek niet zo moeilijk. Cucumber 4 voert elke individuele test van begin tot eind uit op een speciale thread, dus een aantal veelvoorkomende statische zaken werden eenvoudigweg omgezet naar ThreadLocal-variabelen. 
Het belangrijkste bij het converteren met behulp van Idea-refactoringtools is het controleren van de plaatsen waar de variabele is vergeleken (bijvoorbeeld controleren op nul). Bovendien moet u de Allure-plug-in toevoegen aan de Junit Runner-klasseannotatie.

Voorbeeld van het instellen van autotests:

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

Implementeren, opschalen: ervaring met het gebruik van geautomatiseerde tests bij VTBVoorbeeld van een Allure-rapport (de meest onstabiele test, 5 herhalingen)

Implementeren, opschalen: ervaring met het gebruik van geautomatiseerde tests bij VTBRunnerbelasting tijdens tests (8 cores, 8 GB RAM, 24 threads)

Voors:

  • laag verbruik van hulpbronnen;
  • native ondersteuning van Cucumber - geen extra tools vereist;
  • de mogelijkheid om meer dan 6 threads per processorkern uit te voeren.

Tegens:

  • u moet ervoor zorgen dat de code uitvoering met meerdere threads ondersteunt;
  • de instapdrempel wordt hoger.

Allure rapporteert op GitLab-pagina's

Nadat we uitvoering met meerdere threads hadden geïntroduceerd, zijn we veel meer tijd gaan besteden aan het analyseren van rapporten. Destijds moesten we elk rapport als een artefact naar GitLab uploaden, het vervolgens downloaden en uitpakken. Het is niet erg handig en duurt lang. En als iemand anders het rapport zelf wil bekijken, moet hij dezelfde handelingen uitvoeren. We wilden sneller feedback ontvangen en we hebben een oplossing gevonden: GitLab-pagina's. Dit is een ingebouwde functie die standaard beschikbaar is in alle recente versies van GitLab. Hiermee kunt u statische sites op uw server implementeren en deze openen via een directe link.

Alle schermafbeeldingen van Allure-rapporten zijn gemaakt op GitLab-pagina's. Script voor het implementeren van het rapport op GitLab-pagina's - in Windows PowerShell (hiervoor moet u autotests uitvoeren):

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

Zodat 

Dus als je erover nadenkt of je Thread-safe code nodig hebt in het Cucumber autotest-framework, dan ligt het antwoord voor de hand: met Cucumber 4 is het eenvoudig te implementeren, waardoor het aantal gelijktijdig gelanceerde threads aanzienlijk toeneemt. Bij deze manier van testen gaat het om de prestaties van de machine met Selenoid en de testbank.

De praktijk heeft uitgewezen dat het uitvoeren van autotests op threads u in staat stelt het resourceverbruik tot een minimum te beperken met de beste prestaties. Zoals uit de grafieken blijkt, leidt het verdubbelen van threads niet tot een vergelijkbare versnelling in prestatietests. We hebben echter meer dan 2 geautomatiseerde tests aan de applicatie-build kunnen toevoegen, die zelfs met 200 herhalingen in ongeveer 5 minuten worden uitgevoerd. Hierdoor kunt u snel feedback van hen ontvangen en indien nodig wijzigingen aanbrengen en de procedure opnieuw herhalen.

Bron: www.habr.com

Voeg een reactie