Implementa, scala: sperienza di utilizà testi automatizati à VTB

A nostra divisione crea pipeline cumplettamente automatiche per lancià novi versioni di applicazioni in l'ambiente di produzzione. Di sicuru, questu hè bisognu di teste funziunali automatizati. Sottu u cut hè una storia nantu à cumu, cuminciendu cù una prova di filu unicu nantu à una macchina lucale, avemu ghjuntu à u puntu di l'autotest multi-threaded in esecuzione in Selenoid in a pipeline di custruzzione cù un rapportu Allure nantu à e pagine di GitLab è, eventualmente, uttene un strumentu d'automatizazione cool. chì e persone futuri ponu aduprà squadre.

Implementa, scala: sperienza di utilizà testi automatizati à VTB

Induve avemu principiatu ?

Per implementà l'autotests è integrà in u pipeline, avemu bisognu di un quadru d'automatizazione chì puderia esse cambiatu in modu flessibile per adattà à i nostri bisogni. Ideale, vulia ottene un standard unicu per u mutore di l'autotest, adattatu per incrustà l'autotest in u pipeline. Per l'implementazione avemu sceltu e seguenti tecnulugia:

  • Java,
  • Maven,
  • seleniu,
  • Cucumber + JUNIT 4,
  • Allure,
  • GitLab.

Implementa, scala: sperienza di utilizà testi automatizati à VTB

Perchè stu set particulare? Java hè una di e lingue più populari per i testi automatizati, è tutti i membri di a squadra a parlanu. U seleniu hè a suluzione ovvia. Cucumber, tra l'altri cose, duverebbe aumentà a fiducia in i risultati di e teste automatizate da parte di i dipartimenti implicati in testi manuali.

Testi unicu filatu

Per ùn reinventà a rota, avemu pigliatu sviluppi da diversi repositori in GitHub cum'è a basa per u quadru è l'adattamu per noi. Avemu creatu un repository per a biblioteca principale cù u core di u quadru di l'autotest è un repository cù un esempiu Gold di implementazione di autotest in u nostru core. Ogni squadra hà avutu à piglià l'imaghjini d'oru è sviluppà testi in questu, adattendu à u so prughjettu. L'avemu implementatu à u bancu GitLab-CI, nantu à quale avemu cunfiguratu:

  • corse ogni ghjornu di tutti l'autotest scritti per ogni prughjettu;
  • lancia in u pipeline di custruzzione.

À u principiu, ci sò stati pochi testi, è sò stati realizati in un flussu. L'esecuzione di un filu unicu nantu à u Windows runner GitLab ci hè stata abbastanza bè: i testi anu caricatu u bancu di prova assai ligeramente è ùn anu utilizatu quasi nisuna risorsa.

À u tempu, u nùmeru di l'autotests hè diventatu più è più numarosi, è avemu pensatu à eseguisce in parallelu, quandu una corsa sana cuminciò à piglià circa trè ore. Altri prublemi apparsu ancu:

  • ùn pudemu micca verificà chì i testi eranu stabili;
  • e teste chì sò state eseguite parechje volte in una fila nantu à a macchina lucale qualchì volta si scontranu in CI.

Esempiu di stallà 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>

 Implementa, scala: sperienza di utilizà testi automatizati à VTB
Esempiu di rapportu Allure

 Implementa, scala: sperienza di utilizà testi automatizati à VTB
Carica di runner durante e teste (8 core, 8 GB RAM, 1 thread)
 
Pro di i testi unicu filatu:

  • faciule d'installà è curriri;
  • i lanci in CI sò praticamenti micca diffirenti da i lanciamenti lucali;
  • e teste ùn anu micca affettu l'altri;
  • requisiti minimi per e risorse di i corridori.

I svantaghji di e teste à filu unicu:

  • piglià assai tempu per compie;
  • longa stabilizazione di e teste;
  • usu inefficace di risorse di corridore, usu estremamente bassu.

Testi nantu à fork JVM

Siccomu ùn avemu micca cura di u codice thread-safe quandu implementava u quadru di basa, u modu più ovvi di eseguisce in parallelu era cucumber-jvm-parallel-plugin per Maven. U plugin hè faciule da cunfigurà, ma per un funziunamentu parallelu currettu, l'autotest deve esse eseguitu in navigatori separati. Ùn ci hè nunda di fà, aghju avutu aduprà Selenoid.

U servitore Selenoid hè stata lanciata nantu à una macchina cù core 32 è 24 GB di RAM. U limitu hè statu stabilitu à 48 navigatori - 1,5 fili per core è circa 400 MB di RAM. In u risultatu, u tempu di prova hè stata ridutta da trè ore à 40 minuti. L'accelerazione di e corse hà aiutatu à risolve u prublema di stabilizazione: avà pudemu eseguisce rapidamente novi autotests 20-30 volte finu à chì eramu sicuri ch'elli correvanu in modu affidabile.
U primu svantaghju di a suluzione hè stata l'alta utilizazione di e risorse di u corridore cù un picculu numeru di filamenti paralleli: nantu à 4 core è 8 GB di RAM, i testi currenu stabile in micca più di fili 6. U sicondu svantaghju: u plugin genera classi di runner per ogni scenariu, ùn importa quanti di elli sò lanciati.

Impurtante! Ùn passa micca una variabile cù tags à argLine, per esempiu, cusì:

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

Se passate l'etichetta in questu modu, u plugin generà corridori per tutti i testi, vale à dì, pruvarà à eseguisce tutte e teste, saltendu immediatamente dopu à u lanciu è creendu assai forche JVM.

Hè currettu per scaccià una variabile cù un tag in Corsica tags in i paràmetri di u plugin, vede l'esempiu sottu. Altri metudi chì avemu pruvatu anu prublemi per cunnette u plugin Allure.

Esempiu di tempu di esecuzione per 6 teste brevi cù paràmetri sbagliati:

[INFO] Total time: 03:17 min

Esempiu di u tempu di esecuzione di a prova si trasferisce direttamente u tag à mvn... –Dcucumber.opzioni:

[INFO] Total time: 44.467 s

Esempiu di stallà 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>

Implementa, scala: sperienza di utilizà testi automatizati à VTB
Esempiu di un rapportu Allure (a prova più instabile, 4 ripetizioni)

Implementa, scala: sperienza di utilizà testi automatizati à VTBCarica di runner durante i testi (8 core, 8 GB di RAM, 12 thread)
 
Pros:

  • installazione faciule - basta à aghjunghje un plugin;
  • a capacità di realizà simultaneamente un gran numaru di teste;
  • accelerazione di stabilizazione di prova grazia à u passu 1. 

Cons:

  • Multiple OS / cuntenituri necessarii;
  • altu cunsumu di risorse per ogni forchetta;
  • U plugin hè obsoleto è ùn hè più supportatu. 

Cumu superà a inestabilità 

I banchi di prova ùn sò micca ideali, cum'è l'autotesti stessi. Ùn hè micca surprisante chì avemu una quantità di teste flacky. Venutu in salvezza plugin maven surefire, chì fora di a scatula supporta riavvia testi falluti. Avete bisognu di aghjurnà a versione di u plugin à almenu 2.21 è scrivite una linea cù u numeru di reinicia in u schedariu pom o passà cum'è argumentu à Maven.

Esempiu di stallà autotests:

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

O à l'iniziu: mvn... -Dsurefire.rerunFailingTestsCount=2...
Comu opzione, stabilisce l'opzioni Maven per u script PowerShell (PS1):

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

Pros:

  • ùn ci hè bisognu di perde u tempu per analizà una prova inestabile quandu si crash;
  • I prublemi di stabilità di u bancu di teste ponu esse mitigati.

Cons:

  • i difetti flottanti ponu esse mancati;
  • u tempu di corsa aumenta.

Testi paralleli cù a biblioteca Cucumber 4

U numeru di testi cresce ogni ghjornu. Avemu pensatu di novu à accelerà e corse. Inoltre, aghju vulsutu integrà quant'è più teste pussibule in u pipeline di assemblea di l'applicazione. U fattore criticu era chì a generazione di corridori pigliò troppu longu quandu correva in parallelu cù u plugin Maven.

À quellu tempu, Cucumber 4 era digià statu liberatu, cusì avemu decisu di riscrive u kernel per questa versione. In e note di liberazione ci hè statu prumessu di lanciamentu parallelu à u livellu di filu. In teoria, deve esse:

  • accelerà significativamente a corsa di l'autotest aumentendu u numeru di fili;
  • eliminà a perdita di tempu nantu à a generazione di corridori per ogni autotest.

L'ottimisazione di u quadru per l'autotest multi-threaded ùn hè micca cusì difficiule. Cucumber 4 esegue ogni prova individuale nantu à un filu dedicatu da u principiu à a fine, cusì alcune cose statiche cumuni sò stati cunvertiti solu in variabili ThreadLocal. 
A cosa principalu quandu si cunvertisce cù l'arnesi di refactoring Idea hè di verificà i posti induve a variàbile hè stata paragunata (per esempiu, cuntrollà per null). Inoltre, avete bisognu di aghjunghje u plugin Allure à l'annotazione di classi Junit Runner.

Esempiu di stallà 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>

Implementa, scala: sperienza di utilizà testi automatizati à VTBEsempiu di un rapportu Allure (a prova più instabile, 5 ripetizioni)

Implementa, scala: sperienza di utilizà testi automatizati à VTBCarica di runner durante i testi (8 core, 8 GB di RAM, 24 thread)

Pros:

  • bassu cunsumu di risorse;
  • supportu nativu da Cucumber - ùn hè micca necessariu strumenti supplementari;
  • a capacità di eseguisce più di 6 fili per core di processore.

Cons:

  • avete bisognu di assicurà chì u codice sustene l'esekzione multi-threaded;
  • a soglia di entrata aumenta.

Allure rapporti nantu à e pagine di GitLab

Dopu avè introduttu l'esecuzione multi-threaded, avemu cuminciatu à passà assai più tempu per analizà i rapporti. À quellu tempu, avemu avutu a carica ogni rapportu cum'è un artefattu à GitLab, dopu scaricallu è unpack lu. Ùn hè micca assai còmuda è dura assai tempu. È s'ellu qualcunu vole vede u rapportu per ellu stessu, allora avarà bisognu di fà e stesse operazioni. Vulemu riceve feedback più veloce, è avemu trovu una suluzione - pagine GitLab. Questa hè una funzione integrata chì hè dispunibule fora di a scatula in tutte e versioni recenti di GitLab. Permette di implementà siti statici in u vostru servitore è accede à elli via un ligame direttu.

Tutte e screenshots di i rapporti Allure sò stati pigliati nantu à e pagine di GitLab. Script per implementà u rapportu à e pagine GitLab - in Windows PowerShell (prima di questu avete bisognu di eseguisce autotests):

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

Chì ghjè a linea di fondu 

Allora, s'è vo pensate s'ellu avete bisognu di u codice Thread safe in u framework Cucumber autotest, avà a risposta hè ovvia - cù Cucumber 4 hè faciule da implementà, cusì aumentendu significativamente u numeru di fili lanciati simultaneamente. Cù stu metudu di eseguisce e teste, a quistione diventa avà nantu à u rendiment di a macchina cù Selenoid è u bancu di prova.

A pratica hà dimustratu chì eseguisce autotests nantu à i fili permette di riduce u cunsumu di risorse à u minimu cù u megliu rendimentu. Comu pò esse vistu da i grafici, i fili di duppiu ùn portanu micca à una accelerazione simili in i testi di rendiment. Tuttavia, avemu pussutu aghjunghje più di 2 teste automatizati à a custruzione di l'applicazione, chì ancu cù 200 reruns run in circa 5 minuti. Questu permette di riceve un feedback rapidu da elli, è, se ne necessariu, fate cambiamenti è ripetite a prucedura di novu.

Source: www.habr.com

Add a comment