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