A JUnit tesztek futtatása párhuzamosan Maven-lel
1. Bemutatkozás
Noha a tesztek sorozatos végrehajtása legtöbbször rendben működik, érdemes párhuzamosítani őket a dolgok felgyorsítása érdekében.
Ebben az oktatóanyagban kitérünk a tesztek párhuzamosítására a JUnit és a Maven Surefire beépülő moduljának használatával. Először az összes tesztet egyetlen JVM folyamatban futtatjuk, majd egy több modulos projekttel próbáljuk ki.
2. Maven-függőségek
Kezdjük a szükséges függőségek importálásával. A JUnit 4.7 vagy újabb verziót kell használnunk a Surefire 2.16 vagy újabb verzióval együtt:
junit junit 4.12 teszt
org.apache.maven.plugins maven-surefire-plugin 2.22.0
Dióhéjban a Surefire kétféle módszert kínál a tesztek párhuzamos végrehajtására:
- Többszálas szál egyetlen JVM folyamaton belül
- Több JVM folyamat elágazása
3. Párhuzamos tesztek futtatása
A teszt párhuzamos lefuttatásához egy hosszabbító futót kell használnunk org.junit.runners.ParentRunner.
Azok a tesztek azonban, amelyek nem jelentenek kifejezett tesztfuttatót, működik, mivel az alapértelmezett futó kiterjeszti ezt az osztályt.
Ezután a párhuzamos tesztfuttatás bemutatásához egy tesztcsomagot használunk, amelynek két tesztosztálya van, néhány módszerrel. Valójában a JUnit tesztkészlet bármilyen szabványos megvalósítása megtenné.
3.1. Párhuzamos paraméter használata
Először engedélyezzük a párhuzamos viselkedést a Surefire-ben a párhuzamos paraméter. Megállapítja azt a részletességi szintet, amelyen a párhuzamosságot szeretnénk alkalmazni.
A lehetséges értékek:
- módszerek - külön szálakban futtatja a vizsgálati módszereket
- osztályok - a tesztosztályokat külön szálakban futtatja
- classAndMethods - osztályokat és módszereket külön szálakban futtat
- lakosztályok - párhuzamosan fut lakosztályokat
- suitesAndClasses - külön szálakban fut lakosztályokat és osztályokat
- suitesAndMethods - külön szálakat hoz létre az osztályokhoz és a módszerekhez
- minden - külön szálakban futtatja a csomagokat, osztályokat és módszereket
Példánkban használjuk minden:
minden
Másodszor, határozzuk meg a Surefire által létrehozni kívánt szálak teljes számát. Ezt kétféleképpen tehetjük meg:
Használata szálak száma amely meghatározza a Surefire által létrehozandó szálak maximális számát:
10
Vagy használva useUnlimitedThreads paraméter, ahol CPU magonként egy szál jön létre:
igaz
Alapértelmezés szerint, szálak száma CPU magonként van. Használhatjuk a paramétert perCoreThreadCount a viselkedés engedélyezéséhez vagy letiltásához:
igaz
3.2. Menetszám-korlátozások használata
Tegyük fel, hogy meg akarjuk határozni a létrehozandó szálak számát a módszer, az osztály és a csomag szintjén. Megtehetjük ezt a threadCountMethods, threadCountClasses és threadCountSuites paraméterek.
Kombináljuk ezeket a paramétereket a szálak száma az előző konfigurációból:
2 2 6
Mivel használtuk minden ban ben párhuzamos, meghatároztuk a módszerek, csomagok és osztályok szálszámát. Nem kötelező azonban meghatározni a levél paramétert. A Surefire kikövetkezteti a használni kívánt szálak számát abban az esetben, ha a levélparaméterek kihagyásra kerülnek.
Például, ha threadCountMethods kimarad, akkor csak arról kell gondoskodnunk szálak száma >threadCountClasses + threadCountSuites.
Előfordulhat, hogy korlátozni akarjuk az osztályokhoz, csomagokhoz vagy módszerekhez létrehozott szálak számát, még akkor is, ha korlátlan számú szálat használunk.
Alkalmazhatunk szálszámkorlátozásokat ilyen esetekben is:
igaz 2
3.3. Időkorlát beállítása
Előfordulhat, hogy biztosítanunk kell a teszt végrehajtásának időbeli korlátozását.
Ehhez használhatjuk a parallelTestTimeoutForcedInSeconds paraméter. Ez megszakítja a jelenleg futó szálakat, és az időkorlát letelte után nem hajtja végre a várakozási sorban lévő szálakat:
5
Egy másik lehetőség a használat parallelTestTimeoutInSeconds.
Ebben az esetben csak a várakozási sorban lévő szálak kerülnek végrehajtásra:
3.5
Mindazonáltal mindkét lehetőség esetén a tesztek hibaüzenettel zárulnak, amikor az időtúllépés letelt.
3.4. Figyelmeztetések
A Surefire statikus módszereket hívja @Paraméterek, @Óra előtt, és @Óra után a szülőszálban. Ezért a tesztek párhuzamos futtatása előtt ellenőrizze, hogy vannak-e memóriahibák vagy versenyfeltételek.
A megosztott állapotot mutáló tesztek szintén nem alkalmasak arra, hogy párhuzamosan induljanak.
4. Tesztelje a végrehajtást több modulos Maven projektekben
Mostanáig a tesztek párhuzamos futtatására összpontosítottunk egy Maven modulon belül.
De tegyük fel, hogy több modulunk van egy Maven projektben. Mivel ezeket a modulokat egymás után építik fel, az egyes modulok tesztjeit is egymás után hajtják végre.
Ezt az alapértelmezett viselkedést a Maven használatával megváltoztathatjuk -T paraméter, amely párhuzamosan épít modulokat. Ezt kétféleképpen lehet megtenni.
Vagy megadhatjuk a projekt építése során használandó szálak pontos számát:
mvn -T 4 surefire: teszt
Vagy használja a hordozható verziót, és adja meg a létrehozandó szálak számát CPU-alaponként:
mvn -T 1C surefire: teszt
Akárhogy is, gyorsíthatjuk a teszteket, valamint felépíthetjük a végrehajtási időket.
5. Elágazó JVM-ek
A párhuzamos teszt végrehajtásával a párhuzamos opció esetén a párhuzamosság a szálak segítségével történik a JVM folyamaton belül.
Mivel a szálak ugyanazt a memóriaterületet használják, ez hatékony lehet a memória és a sebesség szempontjából. Előfordulhat azonban, hogy váratlan versenykörülményekkel vagy más finom, egyidejűséggel kapcsolatos teszthibákkal találkozunk. Mint kiderült, ugyanazon memóriaterület megosztása áldás és átok is lehet.
A szálszintű párhuzamossági problémák megelőzése érdekében a Surefire egy másik párhuzamos tesztfuttatási módot biztosít: elágazás és folyamatszintű párhuzamosság. A villás folyamatok ötlete valójában meglehetősen egyszerű. A surefire ahelyett, hogy több szálat ívna és szétosztaná közöttük a tesztelési módszereket, új folyamatokat hoz létre, és ugyanazt az elosztást végzi.
Mivel a különböző folyamatok között nincs megosztott memória, nem fogunk szenvedni azoktól a finom párhuzamossági hibáktól. Természetesen ez a nagyobb memóriahasználat és egy kicsit kisebb sebesség rovására megy.
Egyébként is, a villázás engedélyezéséhez csak a forkCount tulajdonságot, és állítsa bármely pozitív értékre:
3
Itt a surefire legfeljebb három villát hoz létre a JVM-ből, és futtatja benne a teszteket. A. Alapértelmezett értéke forkCount az egyik, ami azt jelenti maven-surefire-plugin létrehoz egy új JVM folyamatot az összes teszt végrehajtására egy Maven modulban.
A forkCount tulajdonság ugyanazt a szintaxist támogatja, mint a -T. Vagyis ha hozzáfűzzük a C az értékhez, ezt az értéket megszorozzuk a rendszerünkben rendelkezésre álló CPU-magok számával. Például:
2.5C
Ezután egy kétmagos gépben a Surefire legfeljebb öt villát tud létrehozni a párhuzamos teszt végrehajtásához.
Alapértelmezés szerint, A Surefire újból felhasználja a létrehozott villákat más tesztekhez. Ha azonban beállítjuk a reuseForks tulajdonhoz hamis, akkor minden egyes villát elpusztít egy tesztosztály lefuttatása után.
Ezenkívül az elágazás letiltásához beállíthatjuk a forkCount nullára.
6. Következtetés
Összefoglalva: a többszálas viselkedés lehetővé tételével és a párhuzamosság mértékének meghatározásával kezdtük a párhuzamos paraméter. Ezt követően korlátozásokat alkalmaztunk a Surefire által létrehozandó szálak számára. Később időkorlát paramétereket állítottunk be a teszt végrehajtási idejének szabályozására.
Végül megvizsgáltuk, hogyan csökkenthetjük az összeépítés végrehajtási idejét, és ezért tesztelhetjük a végrehajtási időket a több modulos Maven projektekben.
Mint mindig, az itt bemutatott kód is elérhető a GitHubon.