Divizioni ynë krijon tubacione plotësisht automatike për lëshimin e versioneve të reja të aplikacioneve në mjedisin e prodhimit. Sigurisht, kjo kërkon teste funksionale të automatizuara. Më poshtë është një histori se si, duke filluar me testimin me një fije në një makinë lokale, arritëm në pikën e autotestit me shumë fije që ekzekutohej në Selenoid në tubacionin e ndërtimit me një raport Allure në faqet e GitLab dhe përfundimisht morëm një mjet të mrekullueshëm automatizimi që njerëzit e ardhshëm të mund të përdorin ekipe.
Ku e nisëm?
Për të zbatuar autotestet dhe për t'i integruar ato në tubacion, na duhej një kornizë automatizimi që mund të ndryshohej në mënyrë fleksibël për t'iu përshtatur nevojave tona. Në mënyrë ideale, doja të merrja një standard të vetëm për motorin e autotestimit, të përshtatur për futjen e autotesteve në tubacion. Për zbatimin, ne zgjodhëm teknologjitë e mëposhtme:
- Java,
- Maven,
- Seleni,
- Kastravec+JUNIT 4,
- Joshje,
- GitLab
Pse ky grup i veçantë? Java është një nga gjuhët më të njohura për teste të automatizuara dhe të gjithë anëtarët e ekipit e flasin atë. Seleni është zgjidhja e dukshme. Kastraveci, ndër të tjera, duhej të rriste besimin në rezultatet e testeve të automatizuara nga ana e departamenteve të përfshira në testimin manual.
Testet me një fije të vetme
Për të mos rishpikur rrotën, ne morëm zhvillime nga depo të ndryshme në GitHub si bazë për kornizën dhe i përshtatëm ato për veten tonë. Ne krijuam një depo për bibliotekën kryesore me bërthamën e kornizës së autotestit dhe një depo me një shembull Gold të zbatimit të autotesteve në thelbin tonë. Secili ekip duhej të merrte imazhin Gold dhe të zhvillonte teste në të, duke e përshtatur atë me projektin e tyre. Ne e vendosëm atë në bankën GitLab-CI, në të cilën konfiguruam:
- ekzekutimet ditore të të gjitha autotesteve me shkrim për secilin projekt;
- niset në tubacionin e ndërtimit.
Në fillim kishte pak teste dhe ato u kryen në një rrjedhë. Vrapimi me një fillesë në versionin e Windows GitLab na përshtatet mjaft mirë: testet e ngarkuan shumë lehtë panelin e provës dhe nuk përdorën pothuajse asnjë burim.
Me kalimin e kohës, numri i autotesteve u bë gjithnjë e më i shumtë dhe ne menduam t'i bënim paralelisht, kur një vrapim i plotë filloi të zgjaste rreth tre orë. U shfaqën edhe probleme të tjera:
- nuk mundëm të verifikonim që testet ishin të qëndrueshme;
- testet që u kryen disa herë me radhë në makinën lokale ndonjëherë u rrëzuan në CI.
Shembull i konfigurimit të autotesteve:
<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>
Shembull i raportit joshës
Ngarkesa e vrapuesit gjatë provave (8 bërthama, 8 GB RAM, 1 fije)
Përparësitë e testeve me një fije:
- lehtë për t'u vendosur dhe ekzekutuar;
- lëshimet në CI praktikisht nuk ndryshojnë nga lëshimet lokale;
- testet nuk ndikojnë në njëri-tjetrin;
- kërkesat minimale për burimet vrapuese.
Disavantazhet e testeve me një fije:
- duhet një kohë shumë e gjatë për të përfunduar;
- stabilizimi i gjatë i testeve;
- përdorimi joefikas i burimeve të vrapuesit, shfrytëzim jashtëzakonisht i ulët.
Testet në pirunët JVM
Meqenëse ne nuk u kujdesëm për kodin e sigurt në fije gjatë zbatimit të kornizës bazë, mënyra më e dukshme për të ekzekutuar paralelisht ishte
Serveri Selenoid u lançua në një makinë me 32 bërthama dhe 24 GB RAM. Kufiri u vendos në 48 shfletues - 1,5 fije për bërthamë dhe rreth 400 MB RAM. Si rezultat, koha e testimit u reduktua nga tre orë në 40 minuta. Përshpejtimi i vrapimeve ndihmoi në zgjidhjen e problemit të stabilizimit: tani ne mund të kryenim shpejt autoteste të reja 20-30 herë derisa të ishim të sigurt se ato funksiononin në mënyrë të besueshme.
E meta e parë e zgjidhjes ishte përdorimi i lartë i burimeve të vrapuesit me një numër të vogël fijesh paralele: në 4 bërthama dhe 8 GB RAM, testet u zhvilluan në mënyrë të qëndrueshme në jo më shumë se 6 fije. Disavantazhi i dytë: shtojca gjeneron klasa konkurruese për çdo skenar, pavarësisht se sa prej tyre janë nisur.
Rëndësishme! Mos kaloni një ndryshore me etiketa tek argLine, për shembull, si kjo:
<argLine>-Dcucumber.options="--tags ${TAGS} --plugin io.qameta.allure.cucumber2jvm.AllureCucumber2Jvm --plugin pretty"</argLine>
…
Mvn –DTAGS="@smoke"
Nëse e kaloni etiketën në këtë mënyrë, shtojca do të gjenerojë vrapues për të gjitha testet, domethënë do të përpiqet të ekzekutojë të gjitha testet, duke i anashkaluar ato menjëherë pas nisjes dhe duke krijuar shumë forks JVM.
Është e saktë të hidhet një ndryshore me një etiketë brenda tags në cilësimet e shtojcave, shihni shembullin më poshtë. Metodat e tjera që testuam kanë probleme me lidhjen e shtojcës Allure.
Shembull i kohës së ekzekutimit për 6 teste të shkurtra me cilësime të pasakta:
[INFO] Total time: 03:17 min
Shembull i kohës së ekzekutimit të testit nëse transferoni drejtpërdrejt etiketën te mvn... –Dcucumber.opsione:
[INFO] Total time: 44.467 s
Shembull i konfigurimit të autotesteve:
<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>
Shembull i një raporti Allure (testi më i paqëndrueshëm, 4 përsëritje)
Ngarkesa e vrapuesit gjatë provave (8 bërthama, 8 GB RAM, 12 fije)
Pro:
- konfigurim i lehtë - thjesht duhet të shtoni një shtojcë;
- aftësia për të kryer njëkohësisht një numër të madh testesh;
- përshpejtimi i stabilizimit të provës falë hapit 1.
Cons:
- Kërkohen OS/kontejnerë të shumtë;
- konsumi i lartë i burimeve për çdo pirun;
- Shtojca është e vjetëruar dhe nuk mbështetet më.
Si të kapërceni paqëndrueshmërinë
Stolat e provës nuk janë ideale, ashtu si vetë autotestet. Nuk është për t'u habitur që ne kemi një numër testesh të lëmuara. Erdhi në shpëtim
Shembull i konfigurimit të autotesteve:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.21.0</version>
<configuration>
….
<rerunFailingTestsCount>2</rerunFailingTestsCount>
….
</configuration>
</plugin>
Ose në fillim: mvn … -Dsurefire.rerunFailingTestsCount=2 …
Si opsion, vendosni opsionet Maven për skriptin PowerShell (PS1):
Set-Item Env:MAVEN_OPTS "-Dfile.encoding=UTF-8 -Dsurefire.rerunFailingTestsCount=2"
Pro:
- nuk ka nevojë të humbni kohë duke analizuar një test të paqëndrueshëm kur ai rrëzohet;
- problemet e stabilitetit të stolit të provës mund të zbuten.
Cons:
- defektet lundruese mund të mungojnë;
- koha e ekzekutimit rritet.
Teste paralele me bibliotekën Cucumber 4
Numri i testeve rritej çdo ditë. Ne përsëri menduam për përshpejtimin e vrapimeve. Përveç kësaj, doja të integroja sa më shumë teste të jetë e mundur në tubacionin e montimit të aplikacionit. Faktori kritik ishte se gjenerimi i vrapuesve zgjati shumë kur vraponte paralelisht duke përdorur shtojcën Maven.
Në atë kohë, Cucumber 4 tashmë ishte lëshuar, kështu që vendosëm të rishkruajmë kernelin për këtë version. Në shënimet e lëshimit na u premtua nisja paralele në nivelin e fillit. Teorikisht kjo duhet të ishte:
- përshpejtoni ndjeshëm ekzekutimin e autotesteve duke rritur numrin e temave;
- eliminoni humbjen e kohës në gjenerimin e vrapuesve për çdo autotest.
Optimizimi i kornizës për autotestet me shumë fije doli të mos ishte aq i vështirë. Cucumber 4 kryen çdo test individual në një fije të dedikuar nga fillimi në fund, kështu që disa gjëra statike të zakonshme u konvertuan thjesht në variabla ThreadLocal.
Gjëja kryesore kur konvertohet duke përdorur mjetet e rifaktorimit të idesë është të kontrolloni vendet ku është krahasuar ndryshorja (për shembull, kontrollimi për null). Përveç kësaj, duhet të shtoni shtojcën Allure në shënimin e klasës Junit Runner.
Shembull i konfigurimit të autotesteve:
<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>
Shembull i një raporti Allure (testi më i paqëndrueshëm, 5 përsëritje)
Ngarkesa e vrapuesit gjatë provave (8 bërthama, 8 GB RAM, 24 fije)
Pro:
- konsumi i ulët i burimeve;
- mbështetje vendase nga Kastravec - nuk kërkohen mjete shtesë;
- aftësia për të ekzekutuar më shumë se 6 thread për çdo bërthamë procesori.
Cons:
- duhet të siguroheni që kodi të mbështesë ekzekutimin me shumë fije;
- pragu i hyrjes rritet.
Raportet e Allure në faqet e GitLab
Pas prezantimit të ekzekutimit me shumë fije, filluam të shpenzojmë shumë më tepër kohë duke analizuar raportet. Në atë kohë, ne duhej të ngarkonim çdo raport si një objekt në GitLab, më pas ta shkarkonim dhe ta shpaketonim. Nuk është shumë i përshtatshëm dhe kërkon shumë kohë. Dhe nëse dikush tjetër dëshiron ta shikojë vetë raportin, atëherë ai do të duhet të bëjë të njëjtat operacione. Ne donim të merrnim komente më shpejt dhe gjetëm një zgjidhje - faqet e GitLab. Ky është një veçori e integruar që është e disponueshme jashtë kutisë në të gjitha versionet e fundit të GitLab. Ju lejon të vendosni faqe statike në serverin tuaj dhe t'i aksesoni ato nëpërmjet një lidhjeje të drejtpërdrejtë.
Të gjitha pamjet e ekranit të raporteve Allure janë marrë në faqet e GitLab. Skript për vendosjen e raportit në faqet e GitLab - në Windows PowerShell (përpara kësaj ju duhet të ekzekutoni autotestet):
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
Cila është përfundimi
Pra, nëse po mendonit nëse keni nevojë për kodin e sigurt të Thread në kornizën e autotestit të Cucumber, tani përgjigjja është e qartë - me Cucumber 4 është e lehtë ta zbatoni atë, duke rritur ndjeshëm numrin e temave të nisura njëkohësisht. Me këtë metodë të ekzekutimit të testeve, pyetja tani bëhet për performancën e makinës me Selenoid dhe stolin e provës.
Praktika ka treguar se ekzekutimi i autotesteve në fije ju lejon të reduktoni konsumin e burimeve në minimum me performancën më të mirë. Siç mund të shihet nga grafikët, dyfishimi i fijeve nuk çon në një përshpejtim të ngjashëm në testet e performancës. Sidoqoftë, ne mundëm të shtonim më shumë se 2 teste të automatizuara në ndërtimin e aplikacionit, të cilat edhe me 200 përsëritje ekzekutohen në rreth 5 minuta. Kjo ju lejon të merrni reagime të shpejta prej tyre dhe, nëse është e nevojshme, të bëni ndryshime dhe të përsërisni procedurën përsëri.
Burimi: www.habr.com