jUnit 4 Petr Fanta
Anotace Test • @Test – Označuje public void metodu, která může být spuštěna jako test
• @Test(expected=Exception.class) – Parametr expected označuje vyjimku, která by měla být v metodě vyvolána
• @Test(timeout=100) – Parametr timeout určuje maximální dobu běhu testu (měřeno v milisekundách)
Asserty • Jsou definované jako statické metody třídy Assert • Jsou zaznamenány pouze asserty, které selžou • Příklady: – – – – – – – –
assertArrayEquals(T[] expecteds, T[] actuals) assertEquals(T expected, T actual) assertFalse(boolean condition) assertNotNull(Object object) assertSame(Object expected, Object actual) assertTrue(boolean condition) assertThat(T actual, org.hamcrest.Matcher
matcher) fail()
Fixtures • Slouží k vytvoření prostředků použitých ve více testech • @Before – Označuje metodu, která je volána před každým testem
• @After – Označuje metodu, která je volána po každém testu
• @BeforeClass – Označuje public static void metodu, která je volána pouze jednou před všemi testy v dané třídě
• @AfterClass – Označuje public static void metodu, která je volána pouze jednou po všech testech v dané třídě
Anotace Ignore • @Ignore – Slouží k označení metody nebo třídy, která se mé vynechat při spuštění testu
• Příklad: @Ignore("Test is ignored as a demonstration") @Test public void testSane() { assertThat(1, is(1)); }
Anotace RunWith • Pokud je třída anotována s @RunWith, použije se ke spuštění testů třída určená v parametru místo defaultního jUnit runneru • Příklad: @RunWith(Suite.class) @SuiteClasses(ATest.class, BTest.class, CTest.class) public class ABCSuite { }
Parametrizované testy • Ke spuštění parametrizovaných testů složí runner Parameterized.class • @Parameters – Označuje public static metodu vracejicí List, kde jednotlivé prvky Object[] jsou použity jako parametry construktoru parametrizované třídy
@RunWith(Parameterized.class) public class FibonacciTest { @Parameters public static List data() { return Arrays.asList(new Object[][] { { 0, 0 }, { 1, 1 }, { 2, 1 }, { 3, 2 }, { 4, 3 }, { 5, 5 }, { 6, 8 } }); }
private int fInput; private int fExpected; public FibonacciTest(int input, int expected) { fInput= input; fExpected= expected; } @Test public void test() { assertEquals(fExpected, Fibonacci.compute(fInput)); } }
Pravidla • Pravidla umožňují předefinování chování každého testu ve třídě • Umožňují přístup k informacím o testu uloženým v jUnit • @Rule – Označuje public field (ne static), které jsou typu odvozeného od TestRule.
• • • • • •
• •
ErrorCollector: umožňuje zachycení více chyb v jednom testu ExpectedException: umožňuje zpracování výjimek vyvolaných uvnitř testu ExternalResource: umožňuje například zpuštění a zastavení serveru TemporaryFolder: slouží k vytváření souborů, které budou po testu smazány TestName: obsahuje jméno testu pro použití v jeho průběhu TestWatcher: přidává logiku k průběhu test (např. událost při neúspěchu testu ) Timeout: nastavuje maximální dobu běhu testu Verifier: způsobí neúspěch testu pokud je objekt v nekorektním stavu
Pravidla - příklady • ErrorCollector public static class UsesErrorCollectorTwice { @Rule public ErrorCollector collector= new ErrorCollector(); @Test public void example() { collector.addError(new Throwable("first thing went wrong")); collector.addError(new Throwable("second thing went wrong")); collector.checkThat(getResult(), not(containsString("ERROR!"))); // all lines will run, and then a combined failure logged at the end. } }
Pravidla - příklady • TemporaryFolder public static class HasTempFolder { @Rule public TemporaryFolder folder= new TemporaryFolder(); @Test public void testUsingTempFolder() throws IOException { File createdFile= folder.newFile("myfile.txt"); File createdFolder= folder.newFolder("subfolder"); // ... } }
Pravidla - příklady
• ExternalResource
public static class UsesExternalResource { Server myServer= new Server(); @Rule public ExternalResource resource= new ExternalResource() { @Override protected void before() throws Throwable { myServer.connect(); }; @Override protected void after() { myServer.disconnect(); };
}; @Test public void testFoo() { new Client().run(myServer); } }
Anotace Category • Slouží k rozdělení testů do různých skupin pomocí „štítků“ • @Category(value) – Slouží k označení tříd testů či testovacích metod – Value je pole libovolných tříd
• Ke spuštění slouží runner Categories.class • K výběru kategorii slouží anotece @IncludeCategory a @ExcludeCategory • K určení tříd testů, ze kterých se bude vybírat slouží anotace @SuiteClasses
public interface FastTests { /* category marker */ } public interface SlowTests { /* category marker */ } public class A { @Test public void a() { fail(); } @Category(SlowTests.class) @Test public void b() { }
} @Category({SlowTests.class, FastTests.class}) public class B { @Test public void c() { } } @RunWith(Categories.class) @IncludeCategory(SlowTests.class) @ExcludeCategory(FastTests.class) @SuiteClasses( { A.class, B.class }) // Note that Categories is a kind of Suite public class SlowTestSuite { // Will run A.b, but not A.a or B.c }
Spuštění – příkazový řádek • Spuštení z príkazové řádky: java org.junit.runner.JUnitCore TestClass1 [...other test classes...]
• V CLASSPATH musí byt uvedeny cesty: – K souborům Junit – Ke zdrojovým souborů, včetně tříd s testy – K použitým knihovnám
Spuštění - Ant 1. Proměnné <property name="bin" value="./bin" /> <property name="lib" value="./lib" /> <property name="junit" value="/path/to/junit.jar" /> <property name="test.class.name" value="MyTestSuite" />
2. CLASSPATH pro JUnit target <path id="test.classpath"> <pathelement location="${classes}" /> <pathelement location="${junit}" />
3. Target pro JUnit <junit fork="yes" haltonfailure="yes">
Ant - HTML <property name="report" value="./report" /> <junit failureproperty="testsFailed"> <junitreport todir="${reports}">
Doporučené postupy • Testy by měly být psány předem – Programujeme pouze to co musíme
• Testovat by se mělo pouze to, co se může pokazit • Testy by se měli pouštět kdykoliv je to možné – (alespoň na část kódu, na které pracujeme)
• Pokud se objeví chyba, nejdříve napíšeme test a až poté opravíme • Proč používat JUnit?
Zdroje • • • •
http://kentbeck.github.com/junit/javadoc/latest/ http://junit.sourceforge.net/doc/cookbook/cookbook.htm http://junit.sourceforge.net/doc/faq/faq.htm https://github.com/kentbeck/junit/wiki