Ipatupad, sukat: karanasan sa paggamit ng mga awtomatikong pagsubok sa VTB

Lumilikha ang aming dibisyon ng ganap na awtomatikong mga pipeline para sa paglulunsad ng mga bagong bersyon ng mga application sa kapaligiran ng produksyon. Siyempre, nangangailangan ito ng mga awtomatikong pagsusuri sa pagganap. Sa ibaba ng cut ay isang kuwento tungkol sa kung paano, simula sa single-thread testing sa isang lokal na makina, naabot namin ang punto ng multi-threaded autotest na tumatakbo sa Selenoid sa build pipeline na may ulat ng Allure sa mga pahina ng GitLab at sa huli ay nakakuha kami ng cool na tool sa automation na ang mga hinaharap na tao ay maaaring gumamit ng mga koponan.

Ipatupad, sukat: karanasan sa paggamit ng mga awtomatikong pagsubok sa VTB

Saan tayo nagsimula?

Upang ipatupad ang mga autotest at isama ang mga ito sa pipeline, kailangan namin ng automation framework na maaaring madaling baguhin upang umangkop sa aming mga pangangailangan. Sa isip, gusto kong makakuha ng iisang pamantayan para sa autotesting engine, na inangkop para sa pag-embed ng mga autotest sa pipeline. Para sa pagpapatupad, pinili namin ang mga sumusunod na teknolohiya:

  • Java,
  • Maven,
  • siliniyum,
  • Pipino+JUNIT 4,
  • pang-akit,
  • GitLab.

Ipatupad, sukat: karanasan sa paggamit ng mga awtomatikong pagsubok sa VTB

Bakit ang partikular na set na ito? Ang Java ay isa sa mga pinakasikat na wika para sa mga awtomatikong pagsubok, at lahat ng miyembro ng koponan ay nagsasalita nito. Ang siliniyum ay ang malinaw na solusyon. Ang pipino, bukod sa iba pang mga bagay, ay dapat na magpataas ng kumpiyansa sa mga resulta ng mga awtomatikong pagsusuri sa bahagi ng mga departamentong kasangkot sa manu-manong pagsusuri.

Mga solong sinulid na pagsubok

Upang hindi muling malikha ang gulong, kinuha namin ang mga pag-unlad mula sa iba't ibang mga repositoryo sa GitHub bilang batayan para sa balangkas at inangkop ang mga ito para sa aming sarili. Gumawa kami ng repository para sa pangunahing library na may core ng autotest framework at repository na may Gold na halimbawa ng pagpapatupad ng mga autotest sa aming core. Ang bawat koponan ay kailangang kumuha ng Gold na imahe at bumuo ng mga pagsubok sa loob nito, iangkop ito sa kanilang proyekto. Na-deploy namin ito sa GitLab-CI bank, kung saan namin na-configure:

  • araw-araw na pagpapatakbo ng lahat ng nakasulat na autotest para sa bawat proyekto;
  • ilulunsad sa pipeline ng build.

Sa una ay may ilang mga pagsubok, at sila ay isinasagawa sa isang stream. Ang single-threaded na tumatakbo sa Windows runner na GitLab ay angkop sa amin: ang mga pagsubok ay nag-load sa test bench nang napakagaan at halos walang mga mapagkukunan.

Sa paglipas ng panahon, ang bilang ng mga autotest ay dumami nang parami, at naisipan naming patakbuhin ang mga ito nang magkatulad, nang ang isang buong pagtakbo ay nagsimulang tumagal ng halos tatlong oras. Ang iba pang mga problema ay lumitaw din:

  • hindi namin ma-verify na ang mga pagsubok ay matatag;
  • ang mga pagsubok na pinatakbo nang maraming beses sa isang hilera sa lokal na makina kung minsan ay nag-crash sa CI.

Halimbawa ng pagse-set up ng mga 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>

 Ipatupad, sukat: karanasan sa paggamit ng mga awtomatikong pagsubok sa VTB
Halimbawa ng ulat ng pang-akit

 Ipatupad, sukat: karanasan sa paggamit ng mga awtomatikong pagsubok sa VTB
Naglo-load ang runner sa panahon ng mga pagsubok (8 core, 8 GB RAM, 1 thread)
 
Mga kalamangan ng mga single-threaded na pagsubok:

  • madaling i-set up at patakbuhin;
  • ang mga paglulunsad sa CI ay halos walang pinagkaiba sa mga lokal na paglulunsad;
  • ang mga pagsubok ay hindi nakakaapekto sa isa't isa;
  • minimum na mga kinakailangan para sa mga mapagkukunan ng runner.

Mga disadvantages ng single-threaded na mga pagsubok:

  • tumagal ng napakatagal na oras upang makumpleto;
  • mahabang pagpapapanatag ng mga pagsubok;
  • hindi mahusay na paggamit ng mga mapagkukunan ng runner, napakababang paggamit.

Mga pagsubok sa JVM forks

Dahil hindi namin inalagaan ang thread-safe code kapag ipinapatupad ang base framework, ang pinaka-halatang paraan para tumakbo nang magkatulad ay pipino-jvm-parallel-plugin para kay Maven. Ang plugin ay madaling i-configure, ngunit para sa tamang parallel na operasyon, ang mga autotest ay dapat na tumakbo sa magkahiwalay na mga browser. Walang magawa, kinailangan kong gumamit ng Selenoid.

Ang Selenoid server ay inilunsad sa isang makina na may 32 core at 24 GB ng RAM. Ang limitasyon ay itinakda sa 48 browser - 1,5 thread bawat core at humigit-kumulang 400 MB ng RAM. Bilang resulta, ang oras ng pagsubok ay nabawasan mula sa tatlong oras hanggang 40 minuto. Ang pagpapabilis sa pagtakbo ay nakatulong sa paglutas ng problema sa pag-stabilize: ngayon ay maaari na kaming mabilis na magpatakbo ng mga bagong autotest nang 20–30 beses hanggang sa matiyak namin na gumagana ang mga ito nang mapagkakatiwalaan.
Ang unang disbentaha ng solusyon ay ang mataas na paggamit ng mga mapagkukunan ng runner na may isang maliit na bilang ng mga parallel na mga thread: sa 4 na mga core at 8 GB ng RAM, ang mga pagsubok ay tumatakbo nang matatag sa hindi hihigit sa 6 na mga thread. Ang pangalawang kawalan: ang plugin ay bumubuo ng mga klase ng runner para sa bawat senaryo, gaano man karami sa mga ito ang inilunsad.

Mahalaga! Huwag magpasa ng variable na may mga tag sa argLine, halimbawa, tulad nito:

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

Kung ipapasa mo ang tag sa ganitong paraan, bubuo ang plugin ng mga runner para sa lahat ng pagsubok, iyon ay, susubukan nitong patakbuhin ang lahat ng pagsubok, laktawan kaagad ang mga ito pagkatapos ilunsad at lumikha ng maraming JVM forks.

Tamang magtapon ng variable na may tag tag sa mga setting ng plugin, tingnan ang halimbawa sa ibaba. Ang iba pang mga pamamaraan na sinubukan namin ay may mga problema sa pagkonekta sa plugin ng Allure.

Halimbawa ng oras ng pagtakbo para sa 6 na maikling pagsubok na may mga maling setting:

[INFO] Total time: 03:17 min

Halimbawa ng test run time kung direkta mong ililipat ang tag sa mvn... –Dcucumber.options:

[INFO] Total time: 44.467 s

Halimbawa ng pagse-set up ng mga 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>

Ipatupad, sukat: karanasan sa paggamit ng mga awtomatikong pagsubok sa VTB
Halimbawa ng ulat ng Allure (ang pinaka-hindi matatag na pagsubok, 4 na muling pagpapalabas)

Ipatupad, sukat: karanasan sa paggamit ng mga awtomatikong pagsubok sa VTBNaglo-load ang runner sa panahon ng mga pagsubok (8 core, 8 GB RAM, 12 thread)
 
Pros:

  • madaling pag-setup - kailangan mo lang magdagdag ng isang plugin;
  • ang kakayahang sabay na magsagawa ng isang malaking bilang ng mga pagsubok;
  • acceleration ng test stabilization salamat sa hakbang 1. 

Cons:

  • Kailangan ng maramihang OS/container;
  • mataas na pagkonsumo ng mapagkukunan para sa bawat tinidor;
  • Luma na ang plugin at hindi na sinusuportahan. 

Paano malalampasan ang kawalang-tatag 

Ang mga test bench ay hindi perpekto, tulad ng mga autotest mismo. Hindi kataka-taka na mayroon tayong maraming mapanlinlang na pagsubok. Dumating upang iligtas maven siguradong plugin, na sa labas ng kahon ay sumusuporta sa pag-restart ng mga nabigong pagsubok. Kailangan mong i-update ang bersyon ng plugin sa hindi bababa sa 2.21 at magsulat ng isang linya na may bilang ng mga pag-restart sa pom file o ipasa ito bilang argumento kay Maven.

Halimbawa ng pagse-set up ng mga autotest:

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

O sa pagsisimula: mvn … -Dsurefire.rerunFailingTestsCount=2 …
Bilang opsyon, itakda ang mga opsyon sa Maven para sa PowerShell script (PS1):

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

Pros:

  • hindi na kailangang mag-aksaya ng oras sa pagsusuri ng hindi matatag na pagsubok kapag nag-crash ito;
  • Ang mga problema sa katatagan ng test bench ay maaaring pagaanin.

Cons:

  • maaaring makaligtaan ang mga lumulutang na depekto;
  • tumataas ang oras ng pagtakbo.

Mga parallel na pagsubok sa library ng Cucumber 4

Ang bilang ng mga pagsubok ay lumago araw-araw. Muli naming naisip na pabilisin ang pagtakbo. Bilang karagdagan, gusto kong isama ang maraming pagsubok hangga't maaari sa pipeline ng application assembly. Ang kritikal na kadahilanan ay ang henerasyon ng mga runner ay masyadong matagal kapag tumatakbo nang magkatulad gamit ang Maven plugin.

Noong panahong iyon, nailabas na ang Cucumber 4, kaya nagpasya kaming muling isulat ang kernel para sa bersyong ito. Sa mga tala sa paglabas ay pinangakuan kami ng parallel na paglulunsad sa antas ng thread. Sa teoryang ito ay dapat na:

  • makabuluhang mapabilis ang pagpapatakbo ng mga autotest sa pamamagitan ng pagtaas ng bilang ng mga thread;
  • alisin ang pagkawala ng oras sa pagbuo ng mga runner para sa bawat autotest.

Ang pag-optimize ng framework para sa mga multi-threaded na autotest ay naging hindi napakahirap. Ang Cucumber 4 ay nagpapatakbo ng bawat indibidwal na pagsubok sa isang nakalaang thread mula simula hanggang katapusan, kaya ang ilang karaniwang mga static na bagay ay na-convert lang sa ThreadLocal variable. 
Ang pangunahing bagay kapag nagko-convert gamit ang mga tool sa refactoring ng Idea ay suriin ang mga lugar kung saan inihambing ang variable (halimbawa, pagsuri para sa null). Bilang karagdagan, kailangan mong idagdag ang plugin ng Allure sa anotasyon ng klase ng Junit Runner.

Halimbawa ng pagse-set up ng mga 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>

Ipatupad, sukat: karanasan sa paggamit ng mga awtomatikong pagsubok sa VTBHalimbawa ng ulat ng Allure (ang pinaka-hindi matatag na pagsubok, 5 muling pagpapalabas)

Ipatupad, sukat: karanasan sa paggamit ng mga awtomatikong pagsubok sa VTBNaglo-load ang runner sa panahon ng mga pagsubok (8 core, 8 GB RAM, 24 thread)

Pros:

  • mababang pagkonsumo ng mapagkukunan;
  • katutubong suporta mula sa Pipino - walang karagdagang mga tool na kinakailangan;
  • ang kakayahang magpatakbo ng higit sa 6 na mga thread sa bawat core ng processor.

Cons:

  • kailangan mong tiyakin na sinusuportahan ng code ang multi-threaded execution;
  • tumataas ang entry threshold.

Mga ulat ng Allure sa mga pahina ng GitLab

Matapos ipakilala ang multi-threaded execution, nagsimula kaming gumugol ng mas maraming oras sa pagsusuri ng mga ulat. Sa oras na iyon, kailangan naming i-upload ang bawat ulat bilang isang artifact sa GitLab, pagkatapos ay i-download ito at i-unpack ito. Ito ay hindi masyadong maginhawa at tumatagal ng mahabang panahon. At kung gusto ng ibang tao na tingnan ang ulat para sa kanilang sarili, kakailanganin nilang gawin ang parehong mga operasyon. Gusto naming makatanggap ng feedback nang mas mabilis, at nakahanap kami ng solusyon - mga pahina ng GitLab. Ito ay isang built-in na feature na available out of the box sa lahat ng kamakailang bersyon ng GitLab. Binibigyang-daan kang mag-deploy ng mga static na site sa iyong server at i-access ang mga ito sa pamamagitan ng direktang link.

Ang lahat ng mga screenshot ng mga ulat ng Allure ay kinuha sa mga pahina ng GitLab. Script para sa pag-deploy ng ulat sa mga pahina ng GitLab - sa Windows PowerShell (bago ito kailangan mong magpatakbo ng mga autotest):

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

Gamit ang resulta na 

Kaya, kung iniisip mo kung kailangan mo ng Thread safe code sa Cucumber autotest framework, ngayon ang sagot ay halata - sa Cucumber 4 madali itong ipatupad, at sa gayon ay makabuluhang tumaas ang bilang ng mga thread na inilunsad nang sabay-sabay. Sa ganitong paraan ng pagpapatakbo ng mga pagsubok, ang tanong ngayon ay nagiging tungkol sa pagganap ng makina na may Selenoid at ang test bench.

Ipinakita ng pagsasanay na ang pagpapatakbo ng mga autotest sa mga thread ay nagbibigay-daan sa iyong bawasan ang pagkonsumo ng mapagkukunan sa pinakamababa na may pinakamahusay na pagganap. Tulad ng makikita mula sa mga graph, ang pagdodoble ng mga thread ay hindi humahantong sa isang katulad na acceleration sa mga pagsubok sa pagganap. Gayunpaman, nakapagdagdag kami ng higit sa 2 automated na pagsubok sa pagbuo ng application, na kahit na may 200 rerun ay tumatakbo sa loob ng humigit-kumulang 5 minuto. Pinapayagan ka nitong makatanggap ng mabilis na feedback mula sa kanila, at, kung kinakailangan, gumawa ng mga pagbabago at ulitin muli ang pamamaraan.

Pinagmulan: www.habr.com

Magdagdag ng komento