JUnit 是Java語言標(biāo)準(zhǔn)單元測試庫。JUnit4 放棄了過去嚴(yán)格的命名規(guī)范、繼承層次,轉(zhuǎn)而采用了Java 5 的Annotation機(jī)制,從而簡化測試。本文詳細(xì)介紹了JUnit4 的基本用法,后續(xù)還會針對Matcher、Rule、Theories等主題進(jìn)行一系列學(xué)習(xí)總結(jié)。
什么是JUnit?
JUnit 由XP(極限編程)和TDD(測試驅(qū)動(dòng)開發(fā))的創(chuàng)始人、軟件大師Kent Back以及Eclipse架構(gòu)師之一、設(shè)計(jì)模式之父Erich Gamma共同打造。正如『教父』- Martin Fowler 所說,“在軟件開發(fā)領(lǐng)域,從來沒有如此少的代碼起到了如此重要的作用”。由于 JUnit,Java 代碼變得更健壯,更可靠,bug 也比以前更少。JUnit(它本身的靈感來自 Smalltalk 的 SUnit)衍生了許多 xUnit 工具,將單元測試的優(yōu)勢應(yīng)用于各種語言。nUnit (.NET)、pyUnit (Python)、CppUnit (C++)、dUnit (Delphi) 以及其他工具,影響了各種平臺和語言上的程序員的測試工作。
什么是Annotation
Annotation是Java 5 引入的新特性,它為程序元素(類、變量、方法)添加一個(gè)說明,這些說明可看做『元數(shù)據(jù)』,與業(yè)務(wù)邏輯無關(guān),僅提供給框架分析使用。利用這些『元數(shù)據(jù)』,框架決定如何使用這些程序元素或改變他們的行為。
JUnit4 新框架的特點(diǎn)是什么
JUnit4相比之前版本更輕量,更優(yōu)雅。它放棄了嚴(yán)格的繼承層次、命名規(guī)范,選擇了靈活的Java5 Annotation。用 Beck 的話來說,"JUnit 4 的主題是通過進(jìn)一步簡化 JUnit,鼓勵(lì)更多的開發(fā)人員編寫更多的測試。"
JUnit4 基本用法
1、測試方法
測試方法必須使用public void修飾
測試方法不能有參數(shù)列表
測試方法使用@Test修飾
例如:
import org.junit.Assert;
public class AddTest {
private int x = 1;
private int y = 1;
@Test
public void add() {
int result = x + y;
Assert.assertEquals(2, result);
}
}
2、測試固件
固件通過一個(gè)契約來倡導(dǎo)重用,該契約確保特殊邏輯(初始化數(shù)據(jù)庫、網(wǎng)絡(luò)連接、消除資源等)在測試之前或之后運(yùn)行。
針對每個(gè)測試運(yùn)行一次固件: @Before @After
為整個(gè)類運(yùn)行一次固件: @BeforeClass @AfterClass 。它有可能會違反測試的獨(dú)立性,并引入非預(yù)期的混亂。如果一個(gè)測試在某種程度上改變了@BeforeClass所初始化的一個(gè)對象,那么會引入順序依賴,有可能會影響其他測試結(jié)果,隱藏 bug。
3、測試套件
套件用于將測試用例從邏輯上進(jìn)行分組。在JUnit4中使用兩個(gè)新注釋表達(dá)套件的語義。
@RunWith:使用它是為了讓不同的運(yùn)行器執(zhí)行特別的測試類。為了運(yùn)行測試套件,JUnit4綁定了叫做Suite的套件運(yùn)行器,必須在@RunWith中指定該運(yùn)行器-@RunWith(Suite.class)
@SuiteClasses:該注釋需傳入表示測試套件類的列表參數(shù)
4、異常測試
舊的JUnit異常測試是首先將待測函數(shù)放在try塊,然后在try的末尾加入fail語句,后在catch模塊中捕捉該異常。JUnit4是通過編寫拋出異常的代碼,并使用注釋(@Test聲明expected參數(shù))來聲明該異常是預(yù)期的,如果該異常沒有拋出,則該測試將失敗。
@Test(expected=exceptionName.class)
@Test(expected=ArithmeticException.class)
public void divideByZero(){
int result=5/0
}
5、性能-時(shí)間測試
性能測試一直都是單元測試的痛點(diǎn)之一,JUnit4沒有完全解決該問題,但是它對性能測試-時(shí)間這個(gè)問題有所幫助。測試可以用一個(gè)超時(shí)參數(shù)來注釋,如果測試時(shí)間超過該超時(shí)參數(shù),則測試失敗。
@Test(time=number),其中number是以ms為單位
@Test(time=100)
public void getContentsFromNet(){
net.query("abc");
}
6、忽略測試
某些測試用例因?yàn)樗龅墓ぷ鞅容^復(fù)雜或者緩慢,例如訪問遠(yuǎn)程網(wǎng)絡(luò),因此這些用例運(yùn)行時(shí)間會比較長;又或者某些測試用例因其他原因?qū)е率。瑫簳r(shí)無法運(yùn)行。那么這類測試都可以先暫時(shí)忽略,等后續(xù)再做這類測試。
@Ignore注釋測試方法,則測試運(yùn)行器不會運(yùn)行該測試方法,在測試結(jié)果中會顯示本次運(yùn)行測試pass數(shù)、fail數(shù)、ignore數(shù)。
7、測試運(yùn)行器
JUnit中所有測試方法都是由它均是由測試運(yùn)行器負(fù)責(zé)執(zhí)行,JUnit為單元測試提供了默認(rèn)的運(yùn)行器,但是并未限制只能使用默認(rèn)運(yùn)行器,也可以通過繼承org.junit.runner.Runner來定制自己的運(yùn)行器。因此可以為每個(gè)測試類指定使用某個(gè)特定的測試運(yùn)行器,指定方法是通過@Runner中顯示指名特定測試運(yùn)行器。例如測試套件使用@RunWith(Suite.class)。