Implementera, skala: erfarenhet av att använda automatiserade tester på VTB

Vår division skapar helautomatiska pipelines för att lansera nya versioner av applikationer i produktionsmiljön. Detta kräver naturligtvis automatiserade funktionstester. Nedanför snittet finns en berättelse om hur vi, med början med entrådstestning på en lokal maskin, nådde punkten av flertrådig autotest som kördes på Selenoid i byggpipelinen med en Allure-rapport på GitLab-sidor och så småningom fick ett coolt automationsverktyg att framtida människor kan använda team.

Implementera, skala: erfarenhet av att använda automatiserade tester på VTB

Var började vi?

För att implementera autotester och integrera dem i pipeline behövde vi ett automationsramverk som kunde ändras flexibelt för att passa våra behov. Helst ville jag få en enda standard för autotestmotorn, anpassad för att bädda in autotester i pipeline. För implementering valde vi följande tekniker:

  • Java,
  • Maven,
  • Selen,
  • Gurka+JUNIT 4,
  • Locka,
  • GitLab.

Implementera, skala: erfarenhet av att använda automatiserade tester på VTB

Varför just denna uppsättning? Java är ett av de mest populära språken för automatiserade tester, och alla teammedlemmar talar det. Selen är den självklara lösningen. Gurka var bland annat tänkt att öka förtroendet för resultaten av automatiserade tester hos avdelningar som är involverade i manuella tester.

Enkelgängade tester

För att inte uppfinna hjulet på nytt tog vi utvecklingar från olika repositories på GitHub som grund för ramverket och anpassade dem för oss själva. Vi skapade ett arkiv för huvudbiblioteket med kärnan i autotestramverket och ett arkiv med ett guldexempel på implementering av autotester på vår kärna. Varje team fick ta guldbilden och utveckla tester i den, anpassa den till sitt projekt. Vi distribuerade den till GitLab-CI-banken, där vi konfigurerade:

  • dagliga körningar av alla skriftliga autotester för varje projekt;
  • lanseras i pipeline.

Till en början var det få tester, och de utfördes i en ström. Enkeltrådad körning på Windows-löparen GitLab passade oss ganska bra: testerna belastade testbänken väldigt lätt och använde nästan inga resurser.

Med tiden blev antalet autotester fler och fler och vi funderade på att köra dem parallellt, när en fullkörning började ta cirka tre timmar. Andra problem dök också upp:

  • vi kunde inte verifiera att testerna var stabila;
  • tester som kördes flera gånger i rad på den lokala maskinen kraschade ibland i CI.

Exempel på hur du ställer in autotester:

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

 Implementera, skala: erfarenhet av att använda automatiserade tester på VTB
Allure rapport exempel

 Implementera, skala: erfarenhet av att använda automatiserade tester på VTB
Löparbelastning under tester (8 kärnor, 8 GB RAM, 1 tråd)
 
Fördelar med entrådiga tester:

  • lätt att installera och köra;
  • lanseringar i CI skiljer sig praktiskt taget inte från lokala lanseringar;
  • tester påverkar inte varandra;
  • minimikrav på löparresurser.

Nackdelar med enkelgängade tester:

  • ta mycket lång tid att slutföra;
  • lång stabilisering av tester;
  • ineffektiv användning av löparresurser, extremt lågt utnyttjande.

Tester på JVM gafflar

Eftersom vi inte tog hand om trådsäker kod när vi implementerade basramverket var det mest uppenbara sättet att köra parallellt gurka-jvm-parallell-plugin för Maven. Insticksprogrammet är lätt att konfigurera, men för korrekt parallelldrift måste autotester köras i separata webbläsare. Det finns inget att göra, jag var tvungen att använda Selenoid.

Selenoid-servern lanserades på en maskin med 32 kärnor och 24 GB RAM. Gränsen sattes till 48 webbläsare - 1,5 trådar per kärna och cirka 400 MB RAM. Som ett resultat minskade testtiden från tre timmar till 40 minuter. Att snabba upp körningarna hjälpte till att lösa stabiliseringsproblemet: nu kunde vi snabbt köra nya autotester 20–30 gånger tills vi var säkra på att de gick tillförlitligt.
Den första nackdelen med lösningen var det höga utnyttjandet av löparresurser med ett litet antal parallella trådar: på 4 kärnor och 8 GB RAM körde testerna stabilt i högst 6 trådar. Den andra nackdelen: plugin genererar löparklasser för varje scenario, oavsett hur många av dem som lanseras.

Viktigt! Skicka inte en variabel med taggar till argLinetill exempel så här:

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

Om du klarar taggen på det här sättet kommer plugin-programmet att generera löpare för alla tester, det vill säga att det kommer att försöka köra alla tester, hoppa över dem direkt efter lanseringen och skapa många JVM-gafflar.

Det är korrekt att lägga in en variabel med en tagg taggar i plugin-inställningarna, se exempel nedan. Andra metoder vi testade har problem med att ansluta Allure-plugin.

Exempel på körtid för 6 korta tester med felaktiga inställningar:

[INFO] Total time: 03:17 min

Exempel på testkörningstid om du direkt överför taggen till mvn... –Gurka.alternativ:

[INFO] Total time: 44.467 s

Exempel på hur du ställer in autotester:

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

Implementera, skala: erfarenhet av att använda automatiserade tester på VTB
Exempel på en Allure-rapport (det mest instabila testet, 4 repriser)

Implementera, skala: erfarenhet av att använda automatiserade tester på VTBLöparbelastning under tester (8 kärnor, 8 GB RAM, 12 trådar)
 
Fördelar:

  • enkel installation - du behöver bara lägga till ett plugin;
  • förmågan att samtidigt utföra ett stort antal tester;
  • acceleration av teststabilisering tack vare steg 1. 

Nackdelar:

  • Flera operativsystem/behållare krävs;
  • hög resursförbrukning för varje gaffel;
  • Plugin-programmet är föråldrat och stöds inte längre. 

Hur man övervinner instabilitet 

Testbänkar är inte idealiska, precis som själva autotesterna. Det är inte förvånande att vi har ett antal fläckiga tester. Kom till undsättning maven surefire plugin, som direkt stöder omstart av misslyckade tester. Du måste uppdatera plugin-versionen till minst 2.21 och skriva en rad med antalet omstarter i pom-filen eller skicka det som ett argument till Maven.

Exempel på hur du ställer in autotester:

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

Eller vid uppstart: mvn … -Dsurefire.rerunFailingTestsCount=2 …
Som ett alternativ, ställ in Maven-alternativ för PowerShell-skriptet (PS1):

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

Fördelar:

  • inget behov av att slösa tid på att analysera ett instabilt test när det kraschar;
  • testbänkens stabilitetsproblem kan mildras.

Nackdelar:

  • flytande defekter kan missas;
  • körtiden ökar.

Parallella tester med Cucumber 4-biblioteket

Antalet tester ökade för varje dag. Vi funderade återigen på att få fart på löpningarna. Dessutom ville jag integrera så många tester som möjligt i pipeline för applikationsmontering. Den kritiska faktorn var att genereringen av löpare tog för lång tid när man körde parallellt med Maven-plugin.

Vid den tiden hade Cucumber 4 redan släppts, så vi bestämde oss för att skriva om kärnan för den här versionen. I release notes blev vi lovade parallell lansering på trådnivå. Teoretiskt borde den ha:

  • påskynda körningen av autotester avsevärt genom att öka antalet trådar;
  • eliminera tidsförlusten på att generera löpare för varje autotest.

Att optimera ramverket för flertrådiga autotester visade sig inte vara så svårt. Cucumber 4 kör varje enskilt test på en dedikerad tråd från början till slut, så några vanliga statiska saker konverterades helt enkelt till ThreadLocal-variabler. 
Det viktigaste när du konverterar med hjälp av Idea-refactoring-verktyg är att kontrollera de platser där variabeln jämfördes (till exempel kontrollera noll). Dessutom måste du lägga till Allure-plugin till Junit Runner-klasskommentaren.

Exempel på hur du ställer in autotester:

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

Implementera, skala: erfarenhet av att använda automatiserade tester på VTBExempel på en Allure-rapport (det mest instabila testet, 5 repriser)

Implementera, skala: erfarenhet av att använda automatiserade tester på VTBLöparbelastning under tester (8 kärnor, 8 GB RAM, 24 trådar)

Fördelar:

  • låg resursförbrukning;
  • inbyggt stöd från gurka - inga ytterligare verktyg krävs;
  • möjligheten att köra mer än 6 trådar per processorkärna.

Nackdelar:

  • du måste se till att koden stöder multitrådad körning;
  • inträdesgränsen ökar.

Allure rapporterar på GitLab-sidor

Efter att ha introducerat multi-threaded exekvering började vi lägga mycket mer tid på att analysera rapporter. Vid den tiden var vi tvungna att ladda upp varje rapport som en artefakt till GitLab, sedan ladda ner den och packa upp den. Det är inte särskilt bekvämt och tar lång tid. Och om någon annan vill se rapporten själv, måste de göra samma operationer. Vi ville få feedback snabbare och vi hittade en lösning - GitLab-sidor. Detta är en inbyggd funktion som är tillgänglig direkt i alla nya versioner av GitLab. Låter dig distribuera statiska webbplatser på din server och komma åt dem via en direktlänk.

Alla skärmdumpar av Allure-rapporter togs på GitLab-sidor. Skript för att distribuera rapporten till GitLab-sidor - i Windows PowerShell (innan detta måste du köra autotester):

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

Vad är resultatet 

Så om du funderade på om du behöver trådsäker kod i ramverket för automatisk test av Cucumber, är svaret nu uppenbart - med Cucumber 4 är det enkelt att implementera det, vilket avsevärt ökar antalet trådar som lanseras samtidigt. Med denna metod att köra tester blir frågan nu om maskinens prestanda med Selenoid och testbänken.

Övning har visat att körning av autotester på trådar gör att du kan minska resursförbrukningen till ett minimum med bästa prestanda. Som framgår av graferna leder inte dubbla trådar till en liknande acceleration i prestandatester. Vi kunde dock lägga till mer än 2 automatiserade tester till applikationsbygget, som även med 200 repriser körs på cirka 5 minuter. Detta gör att du kan få snabb feedback från dem, och vid behov göra ändringar och upprepa proceduren igen.

Källa: will.com

Lägg en kommentar