通常我們要驗(yàn)證一個(gè)方法是否正常因悲,需要用到多組測試用例,當(dāng)然就算全部測試用例通過了勺爱,也不能說明這個(gè)方法沒有 bug晃琳。
一、準(zhǔn)備一個(gè)被測試類
public class Sample2 {
public int add(int numA, int numB) {
return numA + numB;
}
}
二琐鲁、生成對應(yīng)的測試類
public class Sample2Test {
private Sample2 _sample2;
@Before
public void setUp() throws Exception {
_sample2 = new Sample2();
}
@Test
public void add() throws Exception {
assertEquals(3, _sample2.add(1, 2));
}
}
三卫旱、增加批量測試用例的問題
如果通過如下手段,則會有點(diǎn)小問題围段。
@Test
public void add() throws Exception {
assertEquals(3, _sample2.add(1, 2));
assertEquals(4, _sample2.add(2, 2));
assertEquals(5, _sample2.add(3, 2));
assertNotEquals(6, _sample2.add(1, 2));
}
以上的寫法的問題是這些測試用例不是純粹的"單元"誊涯,而是變成系列了,有先后關(guān)系了蒜撮。整個(gè)測試過程只執(zhí)行了一次 setUp 操作暴构,所以說每個(gè)測試用例的環(huán)境是不一樣的。
那么如何做到純粹的單元測試呢段磨?那就是每個(gè)方法每次執(zhí)行只測一個(gè)用例取逾,然后就執(zhí)行 tearDown,當(dāng)然我們不會每次執(zhí)行完之后再去修改assertEquals(3, _sample2.add(1, 2));
中的參數(shù)苹支,這樣效率太低砾隅。
這個(gè)時(shí)候我們就可以通過參數(shù)化標(biāo)注的手段來實(shí)現(xiàn)多組純粹的單元測試。
四债蜜、參數(shù)化測試
先上完整代碼
@RunWith(Parameterized.class)
public class Sample2Test {
private Sample2 _sample2;
int expected = 0;
int input1 = 0;
int input2 = 0;
@Parameterized.Parameters
public static java.util.Collection<Object[]> data() {
return Arrays.asList(new Object[][]{
{3, 1, 2},
{4, 2, 2},
{0, -2, 2}
});
}
public Sample2Test(int expected, int input1, int input2) {
this.expected = expected;
this.input1 = input1;
this.input2 = input2;
}
@Before
public void setUp() throws Exception {
_sample2 = new Sample2();
}
@Test
public void add() throws Exception {
assertEquals(expected, _sample2.add(input1, input2));
}
}
完整的步驟如下
- 先修改 Junit 默認(rèn)的測試運(yùn)行器為參數(shù)化類晴埂,在測試類定義上一行添加
@RunWith(Parameterized.class)
- 生成一個(gè)靜態(tài)的參數(shù)化數(shù)據(jù)工廠方法究反,操作如下
- 按 ctrl + N(CMD + M for Mac),選擇
parameter method
儒洛,再選擇Edit Template
精耐,復(fù)制右側(cè)的模板內(nèi)容到測試類中.
- 填充所需要的測試用例
@Parameterized.Parameters
public static java.util.Collection<Object[]> data() {
return Arrays.asList(new Object[][]{
{3, 1, 2},
{4, 2, 2},
{0, -2, 2}
});
}
- 為測試類添加測試用例的字段
private Sample2 _sample2;
int expected = 0;
int input1 = 0;
int input2 = 0;
- 快捷鍵生成包含三個(gè)字段的構(gòu)造器
public Sample2Test(int expected, int input1, int input2) {
this.expected = expected;
this.input1 = input1;
this.input2 = input2;
}
- 修改測試方法中的數(shù)字常量為字段
@Test
public void add() throws Exception {
assertEquals(expected, _sample2.add(input1, input2));
}
五、查看測試結(jié)果
結(jié)果如下如琅锻,可以看到左側(cè)列表中有三個(gè)測試用例卦停,并且都表示通過了。
六恼蓬、小結(jié)
通過參數(shù)化測試惊完,可以保證測試方法每次執(zhí)行的之后只會測試一個(gè)測試用例,測試完成之后執(zhí)行 tearDown 做清理工作处硬,保證每個(gè)測試用例不會相互影響小槐。
實(shí)現(xiàn)的邏輯是參數(shù)化運(yùn)行器每次讀取一組數(shù)據(jù)的時(shí)候都會重新通過傳入數(shù)據(jù)組給測試類構(gòu)造器,從而創(chuàng)建一個(gè)新對象荷辕,然后執(zhí)行 setUp凿跳、testYourMethod、tearDown 操作桐腌。