@Rule是JUnit4的新特性。利用@Rule我們可以擴充JUnit的功能,在執行case的時候加入測試者特有的操作,而不影響原有的case代碼:減小了特有操作和case原邏輯的耦合。譬如說我們要重複測試某個test方法,當然我們可以在@Test方法裡面寫迴圈。但是如果想把迴圈和測試邏輯分開就可以利用@Rule。我們先實現org.junit.rules.MethodRule介面做實迴圈邏輯,然後把執行個體放在testcase裡面即可:
/**<br /> * Demonstrate MethodRule usage.<br /> * Provide repeatable test methods rule.<br /> *<br /> * @author 盧聲遠 <michaellufhl@yahoo.com.cn><br /> */<br />class RepeatableRule implements MethodRule{<br /> //Loop times<br />int times=1;<br />//Loop methods<br />String[] testMethods = null;</p><p>RepeatableRule(int times, String[] testMethods){<br />this.times = times;<br />this.testMethods = testMethods;<br />}</p><p>@Override<br />public Statement apply(final Statement base, final FrameworkMethod method, Object target) {<br /> return new Statement() {<br /> @Override<br /> public void evaluate() throws Throwable {<br /> int loopTime = 1;<br /> if(Arrays.asList(testMethods).contains(method.getName())){//test method name matched<br /> loopTime = times;<br /> }<br /> for(int i=0;i<loopTime;i++)//before() and after() are also executed<br /> base.evaluate();<br /> }<br /> };<br />}<br />}<br />public class TestDemo {</p><p>@Rule<br />public MethodRule rule = new RepeatableRule(5, new String[]{"test1"});</p><p>@Test<br />public void test1(){}<br />@Test<br />public void test2(){}<br />}
需要注意的是整個迴圈都算做1個case,如果有一個迴圈發生fail或者exception都算作fail或者exception。當然,利用@Rule還可以做其他的事情。JUnit4自身就提供了幾個現成的實現:
@Rule還支援同時應用多個Rule。譬如您除了要對TestDemo.test1()進行迴圈5次,而且還要在每次case完成的時候列印一下就可以再引用一個Rule。這次我們可以擴充已有的org.junit.rules.TestWatchman:
@Rule<br />public MethodRule rule2 = new TestWatchman(){<br /> @Override<br /> public void finished(FrameworkMethod method) {<br /> System.out.println(method.getName()+" finished.");<br /> }<br />};