JUnit 4.x支援標註方式,可以在撰寫測試案例類別是簡化不少動作。舉個例子來說,若將 使用 JUnit 3.x 中的範例改以 JUnit 4.x的方式來撰寫,可以如下:
- CalculatorTest.java
package test.cc.openhome;
import static org.junit.Assert.*;
import org.junit.*;
import cc.openhome.Calculator;
public class CalculatorTest {
private Calculator calculator;
@Before
public void setUp() {
calculator = new Calculator();
}
@After
public void tearDown() {
calculator = null;
}
@Test
public void testPlus() {
int expected = 5;
int result = calculator.plus(3, 2);
assertEquals(expected, result);
}
@Test
public void testMinus() {
int expected = 1;
int result = calculator.minus(3, 2);
assertEquals(expected, result);
}
}
你 不用再繼承TestCase類別,而可以使用@Test標註測試方 法,方法只需公開、沒有傳回值、沒有參數,名稱則可以任意,JUnit 4中會自動找出有標註@Test的方法並執 行。@Before可用來標示每個測試方法開始前要執行的操作,@After可用來標示每個測試方法完成後要執行的操 作。
注意到,JUnit 4的套件名稱是以org.junit開頭,有別於JUnit 3的junit.framework套件開 頭名稱,所以斷言相關方法,現在是在org.junit.Assert中的靜態方法。為了相容性,你下載的JUnit 4也會附帶舊有的JUnit 3相關類別。
由於不再繼承TestCase,通常會 稱這個類別為測試類別(Test class),一個測試類別用來集合相關的測試。要執行這個測試類別,可以如下:
C:\workspace\calculator>javac
-sourcepath src -cp lib/junit-4.8.2.jar;classes -d classes
src/test/cc/openhome/CalculatorTest.java
C:\workspace\calculator>java -cp lib/junit-4.8.2.jar;classes org.junit.runner.JUnitCore test.cc.openhome.CalculatorTest
JUnit version 4.8.2
..
Time: 0.024
OK (2 tests)
C:\workspace\calculator>java -cp lib/junit-4.8.2.jar;classes org.junit.runner.JUnitCore test.cc.openhome.CalculatorTest
JUnit version 4.8.2
..
Time: 0.024
OK (2 tests)
在這邊使用org.junit.runner.JUnitCore來 讀入測試類別並執行測試,org.junit.runner.JUnitCore 是個Facade 類別,會自動判斷使用對應的預設runner來執行測試。例如,對於 使用 JUnit 3.x 中的例子,你也可以使用org.junit.runner.JUnitCore 來執行,在內部,org.junit.runner.JUnitCore 會使用org.junit.internal.runners.JUnit38ClassRunner來運行測試。必要時,你也可以使用org.junit.runner.RunWith標註指定使用哪個 runner。例如:
...
@RunWith(value=org.junit.internal.runners.JUnit38ClassRunner.class)
public class CalculatorTest extends TestCase {
...
}
@RunWith(value=org.junit.internal.runners.JUnit38ClassRunner.class)
public class CalculatorTest extends TestCase {
...
}
JUnit 4內建的runner有:
- org.junit.internal.runners.JUnit38ClassRunner
為了相容性,附帶在JUnit 4中,可運行JUnit
3.x測試案例。
- org.junit.runners.JUnit4
用來運行JUnit 4.x測試類別。
- org.junit.runners.Parameterized
可設定一組參數,在每次運行測試時自動在指定位置給予不同
的參數,之後說明。
- org.junit.runners.Suite
正如同JUnit 3.x中的TestSuite,用來
任意組合測試,本身也是個runner。
在這邊先示範一下org.junit.runners.Parameterized 的使用範例,直接先看程式:
package test.cc.openhome;
import java.util.*;
import static org.junit.Assert.*;
import org.junit.*;
import org.junit.runner.*;
import org.junit.runners.*;
import cc.openhome.Calculator;
@RunWith(value=Parameterized.class)
public class CalculatorTest {
@Parameterized.Parameters
public static Collection<Integer[]> getParameters() {
return Arrays.asList(
new Integer[][] {
{5, 3, 2}, //expected, para1, para2
{3, 1, 2}, //expected, para1, para2
{2, 1, 1} //expected, para1, para2
}
);
}
private int expected;
private int para1;
private int para2;
public CalculatorTest(int expected, int para1, int para2) {
this.expected = expected;
this.para1 = para1;
this.para2 = para2;
}
@Test
public void testPlus() {
Calculator calculator = new Calculator();
int result = calculator.plus(para1, para2);
assertEquals(expected, result);
}
}
在上例中,你使用@RunWith 標註使用的runner是org.junit.runners.Parameterized, 此時你必須提供一個方法傳回一組參數,方法可以使用@Parameterized.Parameters標註,這個方法必須是公開、無參數、傳回一個 Collection,當中每個元素必須是一個一維陣列,陣列中第一個元素放預期值,之後參數值一、參數值二等。
org.junit.runners.Parameterized 會使用你所標註的方法取得Collection,之後建立每個測試類別實例時,依序透過建構式將陣列中的每個元素傳入,如上例中,你就可以使用一組準備好 的參數來運行測試。你的Collection長度多長,就會運行幾次測試,以上例而言,共會運行三次測試。
如果必要的話,你也可以在現有的JUnit 3測試案例中,結合JUnit 4的測試類別,只要使用org.junit.JUnit4TestAdapter。 例如:
public
static Test suite() {
return new JUnit4TestAdapter(CalculatorTest.class);
}
return new JUnit4TestAdapter(CalculatorTest.class);
}