Spúšťanie testov JUnit paralelne s Maven

1. Úvod

Aj keď vykonávanie testov sériovo funguje väčšinou dobre, možno by bolo dobré ich paralelizovať, aby sa veci urýchlili.

V tomto výučbe sa dozvieme, ako paralelizovať testy pomocou JUnit a Maven's Surefire Plugin. Najskôr spustíme všetky testy v jednom procese JVM, potom to skúsime s viacmodulovým projektom.

2. Maven závislosti

Začnime importom požadovaných závislostí. Budeme musieť použiť JUnit 4.7 alebo novší spolu s Surefire 2.16 alebo novším:

 junit junit 4,12 test 
 org.apache.maven.plugins maven-surefire-plugin 2.22.0 

Stručne povedané, program Surefire poskytuje dva spôsoby paralelného vykonávania testov:

  • Multithreading vo vnútri jedného procesu JVM
  • Rozdelenie viacerých procesov JVM

3. Spustenie paralelných testov

Na paralelné spustenie testu by sme mali použiť testovacieho bežca, ktorý sa rozširuje org.junit.runners.ParentRunner.

Avšak aj testy, ktoré nedeklarujú explicitný testovací bežec, fungujú, pretože predvolený bežec rozširuje túto triedu.

Ďalej na demonštráciu vykonania paralelného testu použijeme testovaciu sadu s dvoma testovacími triedami, z ktorých každá má niekoľko metód. V skutočnosti by to stačilo na akúkoľvek štandardnú implementáciu testovacej sady JUnit.

3.1. Použitie paralelného parametra

Najskôr povolíme paralelné správanie v Surefire pomocou paralelne parameter. Uvádza sa v ňom úroveň podrobnosti, na ktorej by sme chceli uplatniť paralelizmus.

Možné hodnoty sú:

  • metódy - spúšťa testovacie metódy v samostatných vláknach
  • triedy - prevádzkuje testovacie triedy v samostatných vláknach
  • classesAndMethods - beží triedy a metódy v samostatných vláknach
  • apartmány - beží suity paralelne
  • suitesAndClasses - prevádzkuje suity a triedy v samostatných vláknach
  • suitesAndMethods - vytvára samostatné vlákna pre triedy a pre metódy
  • všetko - beží sady, triedy aj metódy v samostatných vláknach

V našom príklade používame všetko:

 všetko 

Po druhé, definujme celkový počet vlákien, ktoré má Surefire vytvoriť. Môžeme to urobiť dvoma spôsobmi:

Použitím threadCount ktorý definuje maximálny počet vlákien, ktoré Surefire vytvorí:

10

Alebo pomocou useUnlimitedThreads parameter, kde sa na jedno jadro CPU vytvorí jedno vlákno:

pravda

Predvolene, threadCount je na jadro procesora. Môžeme použiť parameter perCoreThreadCount na povolenie alebo zakázanie tohto správania:

pravda

3.2. Používanie obmedzení počtu vlákien

Teraz povedzme, že chceme definovať počet vlákien, ktoré sa majú vytvoriť na úrovni metódy, triedy a balíka. Môžeme to urobiť pomocou threadCountMethods, threadCountClasses a threadCountSuites parametre.

Spojme tieto parametre s threadCount z predchádzajúcej konfigurácie:

2 2 6

Keďže sme použili všetko v paralelne, definovali sme počty vlákien pre metódy, sady a triedy. Nie je však povinné definovať parameter listu. Program Surefire odvodzuje počet vlákien, ktoré sa majú použiť v prípade, že sú vynechané parametre listu.

Napríklad ak threadCountMethods je vynechaný, potom sa musíme len uistiť threadCount >threadCountClasses + threadCountSuites.

Niekedy môžeme chcieť obmedziť počet vlákien vytvorených pre triedy alebo sady alebo metódy, aj keď používame neobmedzený počet vlákien.

Obmedzenie počtu vlákien môžeme použiť aj v takýchto prípadoch:

pravda 2

3.3. Nastavenie časových limitov

Niekedy možno budeme musieť zabezpečiť, aby bolo vykonávanie testu časovo ohraničené.

K tomu môžeme použiť parallelTestTimeoutForcedInSeconds parameter. Týmto sa prerušia aktuálne spustené vlákna a po uplynutí časového limitu sa nevykonajú žiadne vlákna vo fronte:

5

Ďalšou možnosťou je použitie parallelTestTimeoutInSeconds.

V takom prípade sa zastaví vykonávanie iba vlákien vo fronte:

3.5

Napriek tomu s oboma možnosťami sa testy po uplynutí časového limitu skončia chybovým hlásením.

3.4. Upozornenia

Surefire volá statické metódy anotované s @Parametre, @BeforeClassa @Po hodine v nadradenom vlákne. Pred paralelným spustením testov preto nezabudnite skontrolovať prípadné nekonzistencie pamäte alebo podmienky závodu.

Testy, ktoré mutujú zdieľaný stav, tiež rozhodne nie sú vhodnými kandidátmi na paralelné fungovanie.

4. Vykonanie testu v projektoch s viacerými modulmi Maven

Doteraz sme sa zameriavali na paralelné vykonávanie testov v rámci modulu Maven.

Ale povedzme, že v projekte Maven máme viac modulov. Pretože sa tieto moduly zostavujú postupne, testy pre každý modul sa tiež vykonávajú postupne.

Toto predvolené správanie môžeme zmeniť pomocou nástroja Maven -T parameter, ktorý vytvára moduly paralelne. To sa dá urobiť dvoma spôsobmi.

Môžeme buď určiť presný počet vlákien, ktoré sa majú použiť pri vytváraní projektu:

mvn -T 4 surefire: test

Alebo použite prenosnú verziu a zadajte počet vlákien, ktoré sa majú vytvoriť na jadro procesora:

mvn -T 1C surefire: test

Tak či onak, môžeme urýchliť testy aj zostaviť časy vykonania.

5. Vidlicové JVM

S paralelným vykonaním testu prostredníctvom paralelne možnosť, súbežnosť sa deje vo vnútri procesu JVM pomocou vlákien.

Pretože vlákna zdieľajú rovnaký pamäťový priestor, môže to byť efektívne z hľadiska pamäte a rýchlosti. Môžeme sa však stretnúť s neočakávanými pretekovými podmienkami alebo inými jemnými zlyhaniami testov súvisiacich so súbežnosťou. Ako sa ukázalo, zdieľanie rovnakého priestoru v pamäti môže byť požehnaním aj prekliatím.

Aby sa zabránilo problémom so súbežnosťou na úrovni vlákna, poskytuje Surefire ďalší režim vykonávania paralelného testu: rozvetvenie a súbežnosť na úrovni procesu. Myšlienka forkovaných procesov je vlastne celkom jednoduchá. Namiesto vytvárania viacerých vlákien a distribúcie testovacích metód medzi nimi, surefire vytvára nové procesy a robí rovnakú distribúciu.

Pretože medzi rôznymi procesmi neexistuje zdieľaná pamäť, nebudeme trpieť týmito jemnými chybami súbežnosti. To samozrejme prichádza na úkor väčšieho využitia pamäte a trochu menšej rýchlosti.

Každopádne aby sme umožnili rozvetvenie, musíme jednoducho použiť vidlicaCount vlastnosť a nastavte ju na ľubovoľnú kladnú hodnotu:

3

Tu vytvorí surefire najviac tri vidlice z JVM a vykoná v nich testy. Predvolená hodnota pre vidlicaCount je jeden, čo znamená, že maven-surefire-plugin vytvorí jeden nový proces JVM na vykonanie všetkých testov v jednom module Maven.

The vidlicaCount vlastnosť podporuje rovnakú syntax ako -T. To znamená, že ak pripojíme C. na túto hodnotu sa táto hodnota vynásobí počtom dostupných jadier CPU v našom systéme. Napríklad:

2,5 ° C

Potom v dvojjadrovom stroji môže Surefire vytvoriť najviac päť vidlíc na vykonávanie paralelných testov.

Predvolene, Surefire znovu použije vytvorené vidlice pre ďalšie testy. Ak by sme však nastavili reuseForks majetok do nepravdivé, po vykonaní jednej testovacej triedy zničí každú vidličku.

Aby sme vidlicu deaktivovali, môžeme nastaviť vidlicaCount na nulu.

6. Záver

Ak to zhrnieme, začali sme tým, že sme povolili viacvláknové správanie a definovali sme mieru paralelizmu pomocou paralelne parameter. Následne sme aplikovali obmedzenia počtu vlákien, ktoré by mal Surefire vytvárať. Neskôr sme nastavili parametre časového limitu na riadenie časov vykonania testu.

Nakoniec sme sa pozreli na to, ako môžeme znížiť časy vykonania zostavenia, a teda otestovať časy vykonania v multimodulových projektoch Maven.

Tu uvedený kód je ako vždy k dispozícii na GitHub.


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