一、一個簡單的測試
編寫一個只有一種運算的計算器:
public class Calculator {
public static double divide(int dividend, int divisor) {
return dividend / divisor;
}
}
爲這個方法編寫測試:
public class CalculatorTest {
//允許誤差
private static final double DELTA = 0.01;
@Test
public void testAdd() throws Exception {
assertEquals(3, Calculator.divide(9, 3), DELTA);
}
}
這個測試中使用9除以3測試了方法,但是我們希望使用多組數據進行測試,並且不需要編寫多個方法,這時候可以使用JUnit的參數化測試。
二、參數化測試
在JUnit中,參數化測試有兩種形式,第一種形式是構造函數形式,即JUnit遍歷所提供的所有參數調用構造函數並執行測試方法:
//使用Parameterized Runner執行參數化測試
@RunWith(Parameterized.class)
public class CalculatorTest {
//允許誤差
private static final double DELTA = 0.01;
private int dividend;
private int divisor;
private int result;
public CalculatorTest(int dividend, int divisor, int result) {
this.dividend = dividend;
this.divisor = divisor;
this.result = result;
}
// 用@Parameterized.Parameters註解標註該方法是返回所有參數,被註解的方法必須返
// 回裝載數組的Iterable對象,同時必須爲public,static,當測試執行時,系統會遍歷
// 每組參數(數組)調用構造函數並執行測試。
@Parameterized.Parameters
public static Iterable<Object[]> getParameters() {
return Arrays.asList(new Object[][]{
{9, 3, 3}, {5, 1, 5}, {12, 4, 3}
});
}
//當執行測試後,該方法會運行3次
@Test
public void testDevide throws Exception {
assertEquals(result, Calculator.divide(dividend, divisor), DELTA);
}
}
第二種是變量注入形式,變量的值不通過構造函數初始化,而是通過JUnit注入:
//使用Parameterized Runner執行參數化測試
@RunWith(Parameterized.class)
public class CalculatorTest {
//允許誤差
private static final double DELTA = 0.01;
//使用@Parameter標註public變量,JUnit會遍歷每組參數進行注入
//註解中的整數參數表示注入參數組中的第幾個參數
@Parameter(0)
public int dividend;
@Parameter(1)
public int divisor;
@Parameter(2)
public int result;
// 用@Parameterized.Parameters註解標註該方法是返回所有參數,被註解的方法必須返
// 回裝載數組的Iterable對象,同時必須爲public,static,當測試執行時,系統會遍歷
// 每組參數(數組)調用構造函數並執行測試。
@Parameterized.Parameters
public static Iterable<Object[]> getParameters() {
return Arrays.asList(new Object[][]{
{9, 3, 3}, {5, 1, 5}, {12, 4, 3}
});
}
//當執行測試後,該方法會運行3次
@Test
public void testDivide() throws Exception {
assertEquals(result, Calculator.divide(dividend, divisor), DELTA);
}
}
三、Assumption
在上面參數化的例子中,如果我們提供的參數爲{9, 3, 3}, {15, 0, 0}, {12, 4, 3},那第二組參數則會導致測試失敗(15除以0會拋出異常),但是在參數化測試中並不應該使用0爲除數作爲測試,所以應該是測試數據的問題,不應該導致測試失敗。使用org.junit.Assume下的各種assume方法能對測試的數據或者環境做出假設,當這種假設不滿足時跳過該測試,這樣就可以保證在正確的測試環境下執行測試。
@Test
public void testDivide() throws Exception {
//假定除數不爲0,若爲0跳過該測試
assumeTrue("Divisor can't be 0", divisor != 0);
assertEquals(result, Calculator.divide(dividend, divisor), DELTA);
}
使用上述參數執行該測試,第二組參數所對應的測試會被忽略,而不是失敗。