RuleChain - pořadí JUnit interceptorů
Již dvakrát jsem psal o tom, jak na interceptor JUnit testů. Mojí motivací byly screenshoty Selenium testů, ale jen když selžou. Prvním způsobem je vlastní anotace @AfterFailure, což mimo jiné vyžaduje i vlastní test runner. V pozdější verzi JUnit se objevila třída TestWatchman (již deprecated). Největší nevýhodou bylo, že se volá až po metodě anotované @After. Což nevadí do té doby, než se rozhodnete v této metodě zavřít prohlížeč (výsledný screenshot je pak pochopitelně k ničemu). V JUnit verze 4.10 byla naštěstí přidána mocná třída RuleChain.
Nejen v případě Selenium testů použijeme implementace rozhraní TestRule a to konkrétně třídy ExternalResource, TestWatcher a nakonec RuleChain, třída která určuje pořadí jednotlivých TestRule.
import static org.junit.Assert.*; | |
import org.junit.After; | |
import org.junit.Before; | |
import org.junit.Rule; | |
import org.junit.Test; | |
import org.junit.rules.ExternalResource; | |
import org.junit.rules.RuleChain; | |
import org.junit.rules.TestRule; | |
import org.junit.rules.TestWatcher; | |
import org.junit.runner.Description; | |
public class SampleTest { | |
private TestRule seleniumServerRule = new ExternalResource() { | |
@Override | |
protected void before() throws Throwable { | |
System.out.println("start server"); | |
} | |
@Override | |
protected void after() { | |
System.out.println("stop server"); | |
} | |
}; | |
private TestRule screenshotRule = new TestWatcher() { | |
@Override | |
protected void failed(Throwable e, Description description) { | |
String testMethod = description.getClassName() + "#" + description.getMethodName(); | |
System.out.println("Screenshot of the failed test " + testMethod); | |
} | |
}; | |
@Rule | |
public TestRule ruleChain = RuleChain.outerRule(seleniumServerRule).around(screenshotRule); | |
@Before | |
public void setUp() { | |
System.out.println("\tbefore"); | |
} | |
@After | |
public void tearDown() { | |
System.out.println("\tafter"); | |
} | |
@Test | |
public void testA() throws Exception { | |
System.out.println("\t\ttest a"); | |
fail(); | |
} | |
@Test | |
public void testB() throws Exception { | |
System.out.println("\t\ttest b"); | |
} | |
} |
Po spuštění příkladu dostanete následující výstup.
start server before test a after Screenshot of the failed test SampleTest#testA stop server start server before test b after stop server
JUnit nabízí víc možností než jen @Before, @Test a @After. Nezapomeňte se proto podívat i na ostatní implementace rozhraní TestRule.