Pokretanje JUnit testova paralelno s Mavenom

1. Uvod

Iako serijsko izvršavanje testova većinu vremena funkcionira sasvim u redu, možda bismo ih htjeli paralelizirati kako bismo ubrzali stvari.

U ovom vodiču pokazat ćemo kako paralelizirati testove pomoću JUnit-a i Mavenova dodatka Surefire. Prvo ćemo pokrenuti sve testove u jednom JVM procesu, a zatim ćemo pokušati s projektom s više modula.

2. Ovisnosti Mavena

Počnimo s uvozom potrebnih ovisnosti. Morat ćemo koristiti JUnit 4.7 ili noviji, zajedno sa Surefire 2.16 ili novijim:

 test junit junit 4.12 
 org.apache.maven.plugins maven-surefire-plugin 2.22.0 

Ukratko, Surefire nudi dva načina paralelnog izvođenja testova:

  • Multithreading unutar jednog JVM procesa
  • Račvanje više JVM procesa

3. Pokretanje paralelnih testova

Za paralelno pokretanje testa trebali bismo koristiti test trkač koji se proteže org.junit.runners.ParentRunner.

Međutim, čak i testovi koji ne proglašavaju eksplicitni test runner rade, jer zadani runner proširuje ovu klasu.

Dalje, da bismo demonstrirali paralelno izvršavanje testa, upotrijebit ćemo ispitni paket s dvije klase testa, od kojih svaka ima nekoliko metoda. Zapravo bi bila korisna svaka standardna implementacija JUnit paketa za testiranje.

3.1. Korištenje paralelnog parametra

Prvo, omogućimo paralelno ponašanje u Surefireu pomoću paralelno parametar. Navodi razinu razgranatosti na kojoj bismo željeli primijeniti paralelizam.

Moguće vrijednosti su:

  • metode - pokreće metode ispitivanja u zasebnim nitima
  • satovi - pokreće klase ispitivanja u zasebnim nitima
  • classesAndMethods - izvodi klase i metode u zasebnim nitima
  • apartmani - paralelno pokreće apartmane
  • apartmani i klase - pokreće apartmane i klase u zasebnim nitima
  • suitesAndMethods - stvara zasebne niti za klase i za metode
  • svi - pokreće apartmane, klase kao i metode u zasebnim nitima

U našem primjeru koristimo svi:

 svi 

Drugo, definirajmo ukupan broj niti koje želimo da Surefire stvori. To možemo učiniti na dva načina:

Koristeći threadCount koji definira maksimalni broj niti koje će Surefire stvoriti:

10

Ili pomoću useUnlimitedThreads parametar gdje se stvara jedna nit po CPU jezgri:

pravi

Prema zadanim postavkama, threadCount je po CPU jezgri. Možemo koristiti parametar perCoreThreadCount da biste omogućili ili onemogućili ovo ponašanje:

pravi

3.2. Korištenje ograničenja broja brojeva niti

Recimo da sada želimo definirati broj niti koje ćemo stvoriti na razini metode, klase i paketa. To možemo učiniti s threadCountMethods, threadCountClasses i threadCountSuites parametri.

Kombinirajmo ove parametre sa threadCount iz prethodne konfiguracije:

2 2 6

Otkad smo koristili svi u paralelno, definirali smo brojeve niti za metode, apartmane i klase. Međutim, nije obvezno definirati parametar lista. Surefire utvrđuje broj niti koje će se koristiti u slučaju izostavljanja parametara lista.

Na primjer, ako threadCountMethods je izostavljeno, onda samo trebamo biti sigurni threadCount >threadCountClasses + threadCountSuites.

Ponekad ćemo možda htjeti ograničiti broj niti stvorenih za klase ili suite ili metode, čak i dok koristimo neograničen broj niti.

Ograničenja broja konca možemo primijeniti i u takvim slučajevima:

istina 2

3.3. Postavljanje vremenskih ograničenja

Ponekad ćemo možda trebati osigurati da je izvršavanje testa vremenski ograničeno.

Da bismo to učinili, možemo koristiti paralelnoTestTimeutForcedInSekunde parametar. To će prekinuti trenutno pokrenute niti i neće izvršiti niti jednu nit u redu nakon isteka vremena čekanja:

5

Druga mogućnost je korištenje paralelnoTestTimeutInSekunde.

U ovom će se slučaju zaustaviti izvršavanje samo niti u redu:

3.5

Ipak, s obje opcije, testovi će završiti s porukom pogreške kad istekne vremensko ograničenje.

3.4. Upozorenja

Surefire poziva statičke metode označene s @Parameters, @BeforeClass, i @Nakon nastave u nadređenoj niti. Stoga provjerite ima li potencijalnih nedosljednosti u memoriji ili uvjeta utrke prije paralelnog izvođenja testova.

Također, testovi koji mutiraju zajedničko stanje definitivno nisu dobri kandidati za paralelno kandidiranje.

4. Izvršenje testa u višemodularnim projektima Maven

Do sada smo se usredotočili na paralelno izvođenje testova unutar Maven modula.

Ali recimo da imamo više modula u Mavenovom projektu. Budući da se ovi moduli grade sekvencijalno, testovi za svaki modul izvode se i sekvencijalno.

To zadano ponašanje možemo promijeniti pomoću Mavena -T parametar koji paralelno gradi module. To se može učiniti na dva načina.

Možemo odrediti točan broj niti koje ćemo koristiti tijekom izrade projekta:

mvn -T 4 sigurna vatra: test

Ili upotrijebite prijenosnu verziju i navedite broj niti koje će se stvoriti po CPU jezgri:

mvn -T 1C sigurna vatra: test

U svakom slučaju, možemo ubrzati testove, kao i vremena izvršenja izrade.

5. Račvanje JVM-ova

Uz paralelno izvršavanje testa putem paralelno opcija, istodobnost se događa unutar JVM procesa pomoću niti.

Budući da niti dijele isti memorijski prostor, to može biti učinkovito u smislu memorije i brzine. Međutim, možemo naići na neočekivane uvjete utrke ili druge suptilne neuspjehe testa vezane uz istodobnost. Ispostavilo se da dijeljenje istog memorijskog prostora može biti i blagoslov i prokletstvo.

Da bi spriječio probleme s paralelnošću na razini niti, Surefire pruža još jedan paralelni način izvođenja testa: račvanje i istodobnost na razini procesa. Ideja račvastih procesa zapravo je prilično jednostavna. Umjesto da mrijesti više niti i distribuira metode ispitivanja između njih, surefire stvara nove procese i vrši istu distribuciju.

Budući da među različitim procesima nema zajedničke memorije, nećemo patiti od tih suptilnih programskih pogrešaka. Naravno, to dolazi na štetu veće upotrebe memorije i malo manje brzine.

U svakom slučaju, da bismo omogućili račvanje, moramo samo koristiti forkCount svojstvo i postavite ga na bilo koju pozitivnu vrijednost:

3

Ovdje će sigurno JVM stvoriti najviše tri rašlje i pokrenuti testove u njima. Zadana vrijednost za forkCount je jedan, što znači da maven-surefire-plugin stvara jedan novi JVM postupak za izvršavanje svih testova u jednom Maven modulu.

The forkCount svojstvo podržava istu sintaksu kao -T. Odnosno, ako dodamo C na vrijednost, ta će se vrijednost pomnožiti s brojem dostupnih CPU jezgri u našem sustavu. Na primjer:

2,5 ° C

Tada u dvojezgrenom stroju Surefire može stvoriti najviše pet vilica za paralelno izvršavanje testa.

Prema zadanim postavkama, Surefire će ponovno koristiti stvorene rašlje za druge testove. Međutim, ako postavimo ponovno upotrijebitivilice svojstvo da lažno, uništit će svaku vilicu nakon pokretanja jedne test klase.

Također, kako bismo onemogućili račvanje, možemo postaviti forkCount na nulu.

6. Zaključak

Da rezimiramo, započeli smo s omogućavanjem ponašanja s više niti i definiranjem stupnja paralelizma pomoću paralelno parametar. Nakon toga primijenili smo ograničenja na broj niti koje bi Surefire trebao stvoriti. Kasnije postavljamo parametre vremenskog ograničenja za kontrolu vremena izvršavanja testa.

Konačno, pogledali smo kako možemo smanjiti vrijeme izvršavanja gradnje, a time i vrijeme izvršavanja testa u višemodulnim Maven projektima.

Kao i uvijek, ovdje predstavljeni kod dostupan je na GitHubu.


$config[zx-auto] not found$config[zx-overlay] not found