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");
}
}
view raw SampleTest.java hosted with ❤ by GitHub

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.