Paraméterezett tesztek

A JUnit4 lehetővé teszi, hogy tesztjeinket paraméterezzük a @Parameterized.Parameters annotáció segítségével. Így az egyes teszt metódusok többször is végrehajtódnak az előzőleg meghatározott paraméterek listáján végighaladva.

Példaként nézzük meg a Prime Factors Kata bejegyzésben bemutatott teszteket. A Kata végén kilenc tesztesetet tartalmazott a PrimeFactorsTest osztály:

    @Test
    public void one() throws Exception {
        assertEquals(list(), generate(1));
    }

    @Test
    public void two() throws Exception {
        assertEquals(list(2), generate(2));
    }

    ...

    @Test
    public void nine() throws Exception {
        assertEquals(list(3, 3), generate(9));
    }

Jól látszik, hogy mind a kilenc teszteset ugyanazt csinálja, csak más-más értékeket használva. A tesztet paraméterezve mindössze egyetlen tesztmetódusra van szükségünk:

@RunWith(Parameterized.class)
public class PrimeFactorsTest {

    private final int number;
    private final List<Integer> expectedPrimes;

    private static List<Integer> list(Integer... integers) {
        return Arrays.asList(integers);
    }

    @Parameters
    public static Collection<Object[]> parameters() {
        return Arrays.asList(new Object[][] {
                { list(), 1 },
                { list(2), 2 },
                { list(3), 3 },
                { list(2, 2), 4 },
                { list(5), 5 },
                { list(2, 3), 6 },
                { list(7), 7 },
                { list(2, 2, 2), 8 },
                { list(3, 3), 9 }
        });
    }

    public PrimeFactorsTest(List<Integer> expectedPrimes, int number) {
        this.expectedPrimes = expectedPrimes;
        this.number = number;
    }

    @Test
    public void primeFactorsOfAnyNumber() throws Exception {
        assertEquals(expectedPrimes, generate(number));
    }
}

Ahhoz, hogy paramétereket használhassunk, először is el kell látni a tesztosztályt egy @RunWith(Parameterized.class) annotációval (1. sor). Kell készítenünk egy olyan konstruktort, amelyik megkapja a változó paramétereket (26. sor). Ezután egy statikus metódust kell készítenünk, és a @Parameterized.Parameters annotációval ellátnunk (12. sor). Ez a metódus fogja egy Collection formájában visszaadni a paramétereket. A teszt futtatása során ezeket a paramétereket kapja meg a konstruktor egymás után.

Tehát a tesztet lefuttatva kilencszer fog végrehajtódni a primeFactorsOfAnyNumber() teszteset különböző értékekkel, és ugyanazt az eredményt kapjuk, mint a Prime Factors Kata végére elkészült kilenc tesztesetet tartalmazó teszt lefuttatása esetén.

Nincs hozzászólás Írta:
Kategória: Praktikák
Címkék , ,
Kivételek tesztelése JUnit-tal

Gyakran van szükségünk arra, hogy tesztjeinkben megbizonyosodjunk arról, hogy egy adott metódus bizonyos körülmények között kivételt dobjon. Az ilyen helyzeteket JUnit3-al általában a következő mintával kezeltük:

public class ExpectingExceptionsJunit3 extends TestCase {

    public void testExpectedException() throws Exception {
        try {
            ExceptionThrower.throwIOException();
            fail("Exception was expected!");
        } catch (IOException e) {
            assertEquals("Message of the exception", e.getMessage());
        }
    }
}

A fenti teszt akkor fut le sikeresen, ha az ExceptionThrower osztály statikus throwIOException() metódusa egy IOException-t dob, melynek a szövege: “Message of the exception”.

public class ExceptionThrower {

    public static void throwIOException() throws IOException {
        throw new IOException("Message of the exception");
    }

}

A JUnit4 megjelenésével a tesztek annotálhatóvá váltak, és a kivételek tesztelése egyszerűbb lett. A @Test annotáció expected paraméterével megadhatjuk az elvárt kivétel típusát:

public class ExpectingExceptionsJunit4 {

    @Test(expected = IOException.class)
    public void expectedException() throws Exception {
        ExceptionThrower.throwIOException();
    }

}

Több kollégától is hallottam, hogy ezt a módszert azért nem szeretik használni, mert így csak a kivétel típusát ellenőrizhetjük, a szövegét viszont nem, pedig sokszor arra is szükség van. A JUnit4 4.7-es verziójába bekerült Rule-ok használatával ez is könnyen és elegánsan megoldható. Az ExpectedException szabály alkalmazásával a tesztmetóduson belül adhatjuk meg az elvárt kivétel típusát és szövegét.

public class ExpectingExceptionsJunit4 {

    @Rule
    public ExpectedException thrown = ExpectedException.none();

    @Test
    public void expectedException() throws Exception {
        thrown.expect(IOException.class);
        thrown.expectMessage(is("Message of the exception"));

        ExceptionThrower.throwIOException();
    }
}

Mint az a fenti példán is látható, létre kell hoznunk egy publikus ExpectedException típusú mezőt @Rule annotációval. Ezután az egyes tesztesetekben beállíthatjuk a várt kivétel típusát, és szövegét. Az expectMessage() metódus paramétere lehet String (ekkor azt ellenőrzi, hogy a kivétel szövege tartalmazza-e a megadott szöveget), vagy Matcher (amivel gyakorlatilag bármit ellenőrizhetünk).

Nincs hozzászólás Írta:
Kategória: Praktikák
Címkék , , ,
Prime Factors Kata

A kata (型) eredetileg a japán harcművészetek formagyakorlatait jelenti, melyeket mindig ugyanúgy kell végrehajtani. A szoftverfejlesztésben Dave Thomas, a The Pragmatic Programmer társszerzője honosította meg a fogalmat, és a küzdősportokhoz hasonlóan itt is egy olyan rövid gyakorlatot jelent, amit meghatározott lépések szerint célszerű megoldani.

A Prime Factors Kata pedig Robert C. Martinnak (a későbbiekben az egyszerűség kedvéért csak Uncle Bob) köszönhető.

A feladat a következő:

írj egy PrimeFactors nevű osztályt, aminek egyetlen statikus metódusa van, a generate(), ami egy egész számot kap paraméterül és visszaad egy prímtényezőket tartalmazó listát.

Az alábbi videó mutatja be a feladat megoldását Test Driven Development (TDD) módon Eclipse környezetben (gyorsbillentyűk és egyéb finomságok).

http://www.vimeo.com/8636180
1 hozzászólás Írta:
Kategória: Katák
Címkék , ,