Haladni kell a korral (illetve nem szabad lemaradni), úgyhogy átnézegettem a JUnit 4 dolgait. Íme két hasznos olvasmány a témában -egyik az IBM-nél, másik DevX-en. A JUnit 4.X alapvetően a JUnit 3.X továbbgondolása olyan formában, ami a JDK5-ös új feature-jeit jól kihasználja. Jelenleg a 4.4-es verziónál tart, a www.junit.org -ról pedig letölthető (158kbyte a jar forrás nélkül). Mi változott?
- Legalább 5-ös Java kell hozzá (bármilyen meglepő).
- A package megváltozott
junit.framework-rőlorg.junit-ra. @Testannotációk használata névkonvenciók helyett. Továbbra is publicnak ill.void-nak kell lennie a visszatérési értékének és nem lehetnek paraméterei. Ha ezt nem tartjuk be, az alábbi kivételekre számíthatunk:java.lang.Exception: Method xxx should have no parameters
java.lang.Exception: Method xxx should be void- Statikus import használata:
import static org.junit.Assert.assertEquals;Így a kódbanAssert.assertEquals(...);helyett írhatunkassertEquals(...);-t. (Persze JUnit 3.8-nál is használhatjuk a statikus import funkciót, ha 5-ös Javank van.) - Nem kell kiterjeszteni a
TestCaseosztályt, így lehetőve válik a protected metódusok tesztelése azáltal, hogy a teszt-osztállyal a tesztelendő osztályt terjesztjük ki. setUp()metódus helyett a@Beforeannotációt használjuk, akár többet is. Kérdés hogy ezek milyen sorrendben hajtódnak végre - erre a sorrendre nincs explicit szabály, ezért véletlenszerűnek vehető.- A
tearDown()párja pedig az@After, amiből szintén lehet több. - Ősosztályokban nem kell explicite meghívni a
setUp()==@BeforeilletvetearDown()==@Aftermetódusokat, mert azok hívása automatikusan történik: Először az ősosztályban lévő@Before-k hívódnak, aztán a leszármazott osztályokon belüliek.@After-nél pont fordítva, először a leszármazottaké, majd az ősosztályban lévők. - A
@Beforeés@Afterminden teszteset előtt és után hívódik, akárcsak asetUp()éstearDown(). Lehetőség van@BeforeClassés@AfterClassmetódusok megadására, amelyek az osztályban lévő összes teszteset előtt illetve után hívódnak meg. Ilyen feature JUnit 3.X-ben nincs. - Ha egy osztályban nincs egyetlen
@Testannotáció sem, hibát fogunk kapni. - JUnit 3.X-ben a kivételek ellenőrzése úgy történt, hogy a
catchblokkba beírtunk egyassert-et. Itt az annotációba írhatjuk be, hogy milyen kivételt várunk:@Test(expected=ArithmeticException.class). Ha nem dobódik kivétel, vagy más kivétel dobódik, a teszt elbukik. Ha további ellenőrzésekre van szükség a kivétel paramétereivel és szövegével kapcsolatban, továbbra is atry-catchmódszert kell használni. - Ha valami tesztet mégsem akarunk futtatni,
@Ignoreannotációval kiüthetjük. (A@Testannotáció megmaradhat, elé és mögé is beírhatjuk az@Ignore-et.) Megadható neki egy String típusú paraméter, hogy miért hagyjuk ki. A teszt nem fog lefutni, viszont jelezve lesz hogy ki lett hagyva. Az egész osztályra is modhatunk@Ignore-t, de vigyázat, az nem ugyanaz mintha a metódusokra mondanánk, mert az utóbbi esetben még a@AfterClassés@BeforeClasslefut. - Általam nagyra értékelt feature, hogy a teszteseteknek timeout adható így:
@Test(timeout=500)Milliszekundummal. - Van új assert, ami objektum tömböket hasonlít össze, viszont sok (12) assert metódus eltűnt az autoboxing feature miatt. Mindegyik az
assertXXX(Object, Object)-et használja. Illetve a DevX szerint így történt, de én furcsa módon elérem ezeket a mindenféle paraméterű assert metódusokat továbbra is aTestCaseosztályban. - Lehet használni az 1.4-ben bevezetett
assertkulcsszót is, de akkor a tesztek futtatásánál meg kell adni az-eakapcsolót a JVM-nek, különben azassert-ek nem kerülnek kiértékelésre. Ekkor viszont a JUnit-osassertExceptionhelyett a nyelvijava.lang.AssertionError-t fogjuk megkapni adott esetben. - JUnit4-ben nincs
suite()
metódus. Ehelyett lehet csinálni egy üres osztályt, aminek annotációban adjuk meg, hogy milyen más osztályokat futtasson:@RunWith(Suite.class)
@Suite.SuiteClasses({My1Test.class, My2Test.class, My2Test.class})public class AllTests {
} @RunWithosztály annotáció megadásával saját futtatót is megadhatunk a tesztesetek futtatásához. Pl. aorg.junit.runners.Parameterized-et, ami általunk megadott paraméterekkel küldi meg a tesztet. Egy@Parametersannotációval felturbózott publikus statikus metódusra van még szükség, ami egyCollection-t ad vissza és egy publikus konstruktorra, ami a Collection-ben lévő elemeket tudja fogadni. Pl. ha a Collection integer párokat tartalmaz, akkor a konstruktornak is két integer-t kell fogadnia. A futtató végigyalogol a Collection-ön, minden egyes esetben meghívja a konstruktort, majd végig a@Test-tel ellátott metódusokat. A DevX-es cikk harmadik oldalán van erről egy példa. (Listing 2.)- Ha ezt adjuk meg:
@RunWith(TestClassRunner.class)ez nem okoz semmi különbséget ahhoz képest hogy nem adunk meg semmit, mivel aTestClassRunnera default runner. - JUnit4 nem különbözteti meg az előre várt hibákat a rosszul megírt tesztesetekből származő nem várt hibáktól -ez visszalépés! Ergó egy tesztesetnek a JUnit3.8 (passed/error/failure) eseteihez képest csak (passed/failure/(ignored)) esetei vannak.
java –ea org.junit.runner.JUnitCoreparanccsal lehet futtatni a teszteket. Tud futtatni 3.8-as teszteket is a DevX cikk szerint, de a gyakorlatban 3.8-as tesztekben kell egy kis módosítás:public static junit.framework.Test suite() {
return new JUnit4TestAdapter(MyTestClass.class);
4.0-ás tesztek természetesen nem mennek 3.8-on. Ha régi és új JUnit is van a classpath-on, akkor pedig lehet hogy összebalhéznak. Nekem legalábbis securityException-nel leállt.- Hallottam már egy úgynevezett
assertThatmetódusról, elvileg van ilyen 4.4 óta, de még a junit.org-on aktuálisan fenn lévő javadoc-ban nem láttam. - Eclipse 3.3-ban van JUnit4.4 és JUnit3.8 támogatás.
- Olyan szinten el*ja ez a szerkesztő a betűtípusokat és a formázást, hogy öröm nézni. Szörnyű. Update 2007.12.04: Megjavítottam direkt html szerkesztéssel.

1 megjegyzés:
A junit 4 a junit 3 testng-sebbik verzioja :-) en csak azert maradtam meg a junit mellett, mert a testng ide supportja nagyon minimalis. De erdemes kiprobalni, van par agyas dolga, amit a junit meg nem tud.
Megjegyzés küldése