[軟件測(cè)試]JUnit和單元測(cè)試入門(mén)簡(jiǎn)介
1、幾個(gè)相關(guān)的概念
白盒測(cè)試——把測(cè)試對(duì)象看作一個(gè)打開(kāi)的盒子,程序內(nèi)部的邏輯結(jié)構(gòu)和其他信息對(duì)測(cè)試人員是公開(kāi)的。
回歸測(cè)試——軟件或環(huán)境的修復(fù)或更正后的“再測(cè)試”,自動(dòng)測(cè)試工具對(duì)這類(lèi)測(cè)試尤其有用。
單元測(cè)試——是最小粒度的測(cè)試,以測(cè)試某個(gè)功能或代碼塊。一般由程序員來(lái)做,因?yàn)樗枰纼?nèi)部程序設(shè)計(jì)和編碼的細(xì)節(jié)。
JUnit ——是一個(gè)開(kāi)發(fā)源代碼的Java測(cè)試框架,用于編寫(xiě)和運(yùn)行可重復(fù)的測(cè)試。他是用于單元測(cè)試框架體系xUnit的一個(gè)實(shí)例(用于java語(yǔ)言)。主要用于白盒測(cè)試,回歸測(cè)試。
2、單元測(cè)試概述
2.1、單元測(cè)試的好處
A、提高開(kāi)發(fā)速度——測(cè)試是以自動(dòng)化方式執(zhí)行的,提升了測(cè)試代碼的執(zhí)行效率。
B、提高軟件代碼質(zhì)量——它使用小版本發(fā)布至集成,便于實(shí)現(xiàn)人員除錯(cuò)。同時(shí)引入重構(gòu)概念,讓代碼更干凈和富有彈性。
C、提升系統(tǒng)的可信賴度——它是回歸測(cè)試的一種。支持修復(fù)或更正后的“再測(cè)試”,可確保代碼的正確性。
2.2、單元測(cè)試的針對(duì)對(duì)象
A、面向過(guò)程的軟件開(kāi)發(fā)針對(duì)過(guò)程。
B、面向?qū)ο蟮能浖_(kāi)發(fā)針對(duì)對(duì)象。
C、可以做類(lèi)測(cè)試,功能測(cè)試,接口測(cè)試(最常用于測(cè)試類(lèi)中的方法)。
2.3、單元測(cè)試工具和框架
目前的最流行的單元測(cè)試工具是xUnit系列框架,常用的根據(jù)語(yǔ)言不同分為JUnit(java),CppUnit(C++),DUnit (Delphi ),NUnit(.net),PhpUnit(Php )等等。該測(cè)試框架的第一個(gè)和最杰出的應(yīng)用就是由Erich Gamma (《設(shè)計(jì)模式》的作者)和Kent Beck(XP(Extreme Programming)的創(chuàng)始人 )提供的開(kāi)放源代碼的JUnit。
3.Junit入門(mén)簡(jiǎn)介
3.1、JUnit的好處和JUnit單元測(cè)試編寫(xiě)原則
好處:
A、可以使測(cè)試代碼與產(chǎn)品代碼分開(kāi)。
B、針對(duì)某一個(gè)類(lèi)的測(cè)試代碼通過(guò)較少的改動(dòng)便可以應(yīng)用于另一個(gè)類(lèi)的測(cè)試。
C、易于集成到測(cè)試人員的構(gòu)建過(guò)程中,JUnit和Ant的結(jié)合可以實(shí)施增量開(kāi)發(fā)。
D、JUnit是公開(kāi)源代碼的,可以進(jìn)行二次開(kāi)發(fā)。
C、可以方便地對(duì)JUnit進(jìn)行擴(kuò)展。
編寫(xiě)原則:
A、是簡(jiǎn)化測(cè)試的編寫(xiě),這種簡(jiǎn)化包括測(cè)試框架的學(xué)習(xí)和實(shí)際測(cè)試單元的編寫(xiě)。
B、是使測(cè)試單元保持持久性。
C、是可以利用既有的測(cè)試來(lái)編寫(xiě)相關(guān)的測(cè)試。
3.2、JUnit的特征
A、使用斷言方法判斷期望值和實(shí)際值差異,返回Boolean值。
B、測(cè)試驅(qū)動(dòng)設(shè)備使用共同的初始化變量或者實(shí)例。
C、測(cè)試包結(jié)構(gòu)便于組織和集成運(yùn)行。
D、支持圖型交互模式和文本交互模式。
3.3、JUnit框架組成
A、對(duì)測(cè)試目標(biāo)進(jìn)行測(cè)試的方法與過(guò)程集合,可稱為測(cè)試用例(TestCase)。
B、測(cè)試用例的集合,可容納多個(gè)測(cè)試用例(TestCase),將其稱作測(cè)試包(TestSuite)。
C、測(cè)試結(jié)果的描述與記錄。(TestResult) 。
D、測(cè)試過(guò)程中的事件監(jiān)聽(tīng)者(TestListener)。
E、每一個(gè)測(cè)試方法所發(fā)生的與預(yù)期不一致?tīng)顩r的描述,稱其測(cè)試失敗元素(TestFailure)
F、JUnit Framework中的出錯(cuò)異常(AssertionFailedError)。
JUnit框架是一個(gè)典型的Composite模式:TestSuite可以容納任何派生自Test的對(duì)象;當(dāng)調(diào)用TestSuite對(duì)象的run()方法是,會(huì)遍歷自己容納的對(duì)象,逐個(gè)調(diào)用它們的run()方法。(可參考《程序員》2003-6期)。
3.4、JUnit的安裝和配置
JUnit安裝步驟分解:
在http://download.sourceforge.net/junit/中下載JUnit包并將Junit壓縮包解壓到一個(gè)物理目錄中(例如C:\Junit3.8.1)。
記錄Junit.jar文件所在目錄名(例如C:\Junit3.8.1\Junit.jar)。
進(jìn)入操作系統(tǒng)(以Windows2000操作系統(tǒng)為準(zhǔn)),按照次序點(diǎn)擊“開(kāi)始 設(shè)置 控制面板”。
在控制面板選項(xiàng)中選擇“系統(tǒng)”,點(diǎn)擊“環(huán)境變量”,在“系統(tǒng)變量”的“變量”列表框中選擇“CLASS-PATH”關(guān)鍵字(不區(qū)分大小寫(xiě)),如果該關(guān)鍵字不存在則添加。
雙擊“CLASS-PATH”關(guān)鍵字添加字符串“C:\Junit3.8.1\Junti.jar”(注意,如果已有別的字符串請(qǐng)?jiān)谠撟址淖址Y(jié)尾加上分號(hào)“;”),這樣確定修改后Junit就可以在集成環(huán)境中應(yīng)用了。
對(duì)于IDE環(huán)境,對(duì)于需要用到的JUnit的項(xiàng)目增加到lib中,其設(shè)置不同的IDE有不同的設(shè)置 。
3.5、JUnit中常用的接口和類(lèi)
Test接口——運(yùn)行測(cè)試和收集測(cè)試結(jié)果
Test接口使用了Composite設(shè)計(jì)模式,是單獨(dú)測(cè)試用例 (TestCase),聚合測(cè)試模式(TestSuite)及測(cè)試擴(kuò)展(TestDecorator)的共同接口。
它的public int countTestCases()方法,它來(lái)統(tǒng)計(jì)這次測(cè)試有多少個(gè)TestCase,另外一個(gè)方法就是public void run( TestResult ),TestResult是實(shí)例接受測(cè)試結(jié)果, run方法執(zhí)行本次測(cè)試。
TestCase抽象類(lèi)——定義測(cè)試中固定方法
TestCase是Test接口的抽象實(shí)現(xiàn),(不能被實(shí)例化,只能被繼承)其構(gòu)造函數(shù)TestCase(string name)根據(jù)輸入的測(cè)試名稱name創(chuàng)建一個(gè)測(cè)試實(shí)例。由于每一個(gè)TestCase在創(chuàng)建時(shí)都要有一個(gè)名稱,若某測(cè)試失敗了,便可識(shí)別出是哪個(gè)測(cè)試失敗。
TestCase類(lèi)中包含的setUp()、tearDown()方法。setUp()方法集中初始化測(cè)試所需的所有變量和實(shí)例,并且在依次調(diào)用測(cè)試類(lèi)中的每個(gè)測(cè)試方法之前再次執(zhí)行setUp()方法。tearDown()方法則是在每個(gè)測(cè)試方法之后,釋放測(cè)試程序方法中引用的變量和實(shí)例。
開(kāi)發(fā)人員編寫(xiě)測(cè)試用例時(shí),只需繼承TestCase,來(lái)完成run方法即可,然后JUnit獲得測(cè)試用例,執(zhí)行它的run方法,把測(cè)試結(jié)果記錄在TestResult之中。
Assert靜態(tài)類(lèi)——一系列斷言方法的集合
Assert包含了一組靜態(tài)的測(cè)試方法,用于期望值和實(shí)際值比對(duì)是否正確,即測(cè)試失敗,Assert類(lèi)就會(huì)拋出一個(gè)AssertionFailedError異常,JUnit測(cè)試框架將這種錯(cuò)誤歸入Failes并加以記錄,同時(shí)標(biāo)志為未通過(guò)測(cè)試。如果該類(lèi)方法中指定一個(gè)String類(lèi)型的傳參則該參數(shù)將被做為AssertionFailedError異常的標(biāo)識(shí)信息,告訴測(cè)試人員改異常的詳細(xì)信息。
JUnit 提供了6大類(lèi)31組斷言方法,包括基礎(chǔ)斷言、數(shù)字?jǐn)嘌浴⒆址麛嘌浴⒉紶枖嘌浴?duì)象斷言。
其中assertEquals(Object expcted,Object actual)內(nèi)部邏輯判斷使用equals()方法,這表明斷言兩個(gè)實(shí)例的內(nèi)部哈希值是否相等時(shí),最好使用該方法對(duì)相應(yīng)類(lèi)實(shí)例的值進(jìn)行比較。而assertSame(Object expected,Object actual)內(nèi)部邏輯判斷使用了Java運(yùn)算符“==”,這表明該斷言判斷兩個(gè)實(shí)例是否來(lái)自于同一個(gè)引用(Reference),最好使用該方法對(duì)不同類(lèi)的實(shí)例的值進(jìn)行比對(duì)。asserEquals(String message,String expected,String actual)該方法對(duì)兩個(gè)字符串進(jìn)行邏輯比對(duì),如果不匹配則顯示著兩個(gè)字符串有差異的地方。ComparisonFailure類(lèi)提供兩個(gè)字符串的比對(duì),不匹配則給出詳細(xì)的差異字符。
TestSuite測(cè)試包類(lèi)——多個(gè)測(cè)試的組合
TestSuite類(lèi)負(fù)責(zé)組裝多個(gè)Test Cases。待測(cè)得類(lèi)中可能包括了對(duì)被測(cè)類(lèi)的多個(gè)測(cè)試,而TestSuit負(fù)責(zé)收集這些測(cè)試,使我們可以在一個(gè)測(cè)試中,完成全部的對(duì)被測(cè)類(lèi)的多個(gè)測(cè)試。
TestSuite類(lèi)實(shí)現(xiàn)了Test接口,且可以包含其它的TestSuites。它可以處理加入Test時(shí)的所有拋出的異常。
TestSuite處理測(cè)試用例有6個(gè)規(guī)約(否則會(huì)被拒絕執(zhí)行測(cè)試)
A 測(cè)試用例必須是公有類(lèi)(Public)
B 測(cè)試用例必須繼承與TestCase類(lèi)
C 測(cè)試用例的測(cè)試方法必須是公有的( Public )
D 測(cè)試用例的測(cè)試方法必須被聲明為Void
E 測(cè)試用例中測(cè)試方法的前置名詞必須是test
F 測(cè)試用例中測(cè)試方法誤任何傳遞參數(shù)
n TestResult結(jié)果類(lèi)和其它類(lèi)與接口
TestResult結(jié)果類(lèi)集合了任意測(cè)試?yán)奂咏Y(jié)果,通過(guò)TestResult實(shí)例傳遞個(gè)每個(gè)測(cè)試的Run()方法。TestResult在執(zhí)行TestCase是如果失敗會(huì)異常拋出
TestListener接口是個(gè)事件監(jiān)聽(tīng)規(guī)約,可供TestRunner類(lèi)使用。它通知listener的對(duì)象相關(guān)事件,方法包括測(cè)試開(kāi)始startTest(Test test),測(cè)試結(jié)束endTest(Test test),錯(cuò)誤,增加異常addError(Test test,Throwable t)和增加失敗addFailure(Test test,AssertionFailedError t)
TestFailure失敗類(lèi)是個(gè)“失敗”狀況的收集類(lèi),解釋每次測(cè)試執(zhí)行過(guò)程中出現(xiàn)的異常情況。其toString()方法返回“失敗”狀況的簡(jiǎn)要描述
3.6、JUnit一個(gè)實(shí)例
在控制臺(tái)中簡(jiǎn)單的范例如下:
1、寫(xiě)個(gè)待測(cè)試的Triangle類(lèi),創(chuàng)建一個(gè)TestCase的子類(lèi)ExampleTest:
2、 ExampleTest中寫(xiě)一個(gè)或多個(gè)測(cè)試方法,斷言期望的結(jié)果(注意:以test作為待測(cè)試的方法的開(kāi)頭,這樣這些方法可以被自動(dòng)找到并被測(cè)試)
3、 ExampleTest中寫(xiě)一個(gè)suite()方法,它會(huì)使用反射動(dòng)態(tài)的創(chuàng)建一個(gè)包含所有的testXxxx方法的測(cè)試套件:
4、 ExampleTest可以寫(xiě)setUp()、tearDown()方法,以便于在測(cè)試時(shí)初始化或銷(xiāo)毀測(cè)試所需的所有變量和實(shí)例。(不是必須的)
5、寫(xiě)一個(gè)main()方法以文本運(yùn)行器或其它GUI的方式方便的運(yùn)行測(cè)試
6、編譯ExampleTest,執(zhí)行測(cè)試。
3.7、Eclipse中JUnit的使用
Eclipse自帶了一個(gè)JUnit的插件,不用安裝就可以在你的項(xiàng)目中開(kāi)始測(cè)試相關(guān)的類(lèi),并且可以調(diào)試你的測(cè)試用例和被測(cè)試類(lèi)。
使用步驟如下:
1、新建一個(gè)測(cè)試用例,點(diǎn)擊“File->New->Other…菜單項(xiàng),在彈出的“New”對(duì)話框中選擇”Java->JUnit”,下的TestCase 或TestSuite,就進(jìn)入“New JUnit TestCase”對(duì)話框
2、在“New JUnit TestCase”對(duì)話框填寫(xiě)相應(yīng)的欄目,主要有Name(測(cè)試用例名),SuperClass(測(cè)試的超類(lèi)一般是默認(rèn)的junit.framework.TestCase),Class Under Test(被測(cè)試的類(lèi)),Source Folder(測(cè)試用例保存的目錄),Package(測(cè)試用例包名),及是否自動(dòng)生成main,setUp,tearDown方法。
3、如果點(diǎn)擊下面的”Next>”按鈕,你還可以直接勾選你想測(cè)試的被測(cè)試類(lèi)的方法,Eclipse將自動(dòng)生成與被選方法相應(yīng)的測(cè)試方法,點(diǎn)擊“Fishish”按鈕后一個(gè)測(cè)試用例就創(chuàng)建好了。
4、編寫(xiě)完成你的測(cè)試用例后,點(diǎn)擊“Run”按鈕就可以看到運(yùn)行結(jié)果了。
3.8、JUnit的擴(kuò)展應(yīng)用
以下羅列了些JUnit的擴(kuò)展應(yīng)用:
JUnit + HttpUnit=WEB功能測(cè)試工具
JUnit + hansel =代碼覆蓋測(cè)試工具
JUnit + abbot =界面自動(dòng)回放測(cè)試工具
JUnit + dbunit =數(shù)據(jù)庫(kù)測(cè)試工具
JUnit + junitperf=性能測(cè)試工具
3.9、一些使用JUnit經(jīng)驗(yàn)
不要用TestCase的構(gòu)造函數(shù)初始化,而要用setUp()和tearDown()方法。
不要依賴或假定測(cè)試運(yùn)行的順序,因?yàn)镴Unit利用Vector保存測(cè)試方法。所以不同的平臺(tái)會(huì)按不同的順序從Vector中取出測(cè)試方法。
避免編寫(xiě)有副作用的TestCase。例如:如果隨后的測(cè)試依賴于某些特定的交易數(shù)據(jù),就不要提交交易數(shù)據(jù)。簡(jiǎn)單的回滾就可以了。
當(dāng)繼承一個(gè)測(cè)試類(lèi)時(shí),記得調(diào)用父類(lèi)的setUp()和tearDown()方法。
將測(cè)試代碼和工作代碼放在一起,一邊同步編譯和更新。
測(cè)試類(lèi)和測(cè)試方法應(yīng)該有一致的命名方案。如在工作類(lèi)名前加上test從而形成測(cè)試類(lèi)名。
確保測(cè)試與時(shí)間無(wú)關(guān),不要依賴使用過(guò)期的數(shù)據(jù)進(jìn)行測(cè)試。導(dǎo)致在隨后的維護(hù)過(guò)程中很難重現(xiàn)測(cè)試。
如果你編寫(xiě)的軟件面向國(guó)際市場(chǎng),編寫(xiě)測(cè)試時(shí)要考慮國(guó)際化的因素。不要僅用母語(yǔ)的Locale進(jìn)行測(cè)試。
盡可能地利用JUnit提供地assert/fail方法以及異常處理的方法,可以使代碼更為簡(jiǎn)潔。
測(cè)試要盡可能地小,執(zhí)行速度快。
參考資料與附件
1. http:// www.junit.org JUnit官方網(wǎng)站
2. http://bbs.51cmm.com 的測(cè)試論壇
3. http://www.uml.org.cn 的軟件測(cè)試專欄
4. 單元測(cè)試 《程序員》 2002年7期
5. JUnit設(shè)計(jì)模式分析 《程序員》2003年6期
6. 《軟件測(cè)試和JUnit實(shí)踐》
7. 附件Triangle.java 一個(gè)要測(cè)試的類(lèi)
8. 附件ExampleTest.java 一個(gè)測(cè)試用例類(lèi)
Triangle.java
/**
* this is Triangle class
* @author liujun
*/
public class Triangle
{
//定義三角形的三邊
protected long lborderA = 0;
protected long lborderB = 0;
protected long lborderC = 0;
//構(gòu)造函數(shù)
public Triangle(long lborderA,long lborderB,long lborderC)
{
this.lborderA = lborderA;
this.lborderB = lborderB;
this.lborderC = lborderC;
}
/**
* 判斷是否是三角形
* 是返回ture;不是返回false
*/
public boolean isTriangle(Triangle triangle)
{
boolean isTrue = false;
//判斷邊界,大于0小于200,出界返回false
if((triangle.lborderA>0&&triangle.lborderA<200)
&&(triangle.lborderB>0&&triangle.lborderB<200)
&&(triangle.lborderC>0&&triangle.lborderC<200))
{
//判斷兩邊之和大于第三邊
if((triangle.lborderA<(triangle.lborderB+triangle.lborderC))
&&(triangle.lborderB<(triangle.lborderA+triangle.lborderC))
&&(triangle.lborderC<(triangle.lborderA+triangle.lborderB)))
isTrue = true;
}
return isTrue;
}
/**
* 判斷三角形類(lèi)型
* 等腰三角形返回字符串“等腰三角形”;
* 等邊三角形返回字符串“等邊三角形”;
* 其它三角形返回字符串“不等邊三角形”;
*/
public String isType(Triangle triangle)
{
String strType = "";
// 判斷是否是三角形
if(this.isTriangle(triangle))
{
//判斷是否是等邊三角形 if(triangle.lborderA==triangle.lborderB&&triangle.lborderB==triangle.lborderC)
strType = "等邊三角形";
//判斷是否是不等邊三角形
else if((triangle.lborderA!=triangle.lborderB)&&
(triangle.lborderB!=triangle.lborderC)&&
(triangle.lborderA!=triangle.lborderC))
strType = "不等邊三角形";
else
strType="等腰三角形";
}
return strType;
}
}
ExampleTest.java
import junit.framework.*;
/**
* Some tests.
*
*/
public class ExampleTest extends TestCase {
public Triangle triangle;
//初始化
protected void setUp() {
triangle=new Triangle(10,2,9);
}
public static Test suite() {
return new TestSuite(ExampleTest.class);
}
//函數(shù)isTriangle()的測(cè)試用例
public void testIsTriangle() {
assertTrue(triangle.isTriangle(triangle));
}
//函數(shù)isType()的測(cè)試用例
public void testIsType()
{
assertEquals("這次測(cè)試",triangle.isType(triangle),"不等邊三角形");
}
//執(zhí)行測(cè)試
public static void main (String[] args) {
//文本方式
junit.textui.TestRunner.run(suite());
//Swingui方式
//junit.swingui.TestRunner.run(suite().getClass());
//awtui方式
//junit.awtui.TestRunner.run(suite().getClass());
}
}
白盒測(cè)試——把測(cè)試對(duì)象看作一個(gè)打開(kāi)的盒子,程序內(nèi)部的邏輯結(jié)構(gòu)和其他信息對(duì)測(cè)試人員是公開(kāi)的。
回歸測(cè)試——軟件或環(huán)境的修復(fù)或更正后的“再測(cè)試”,自動(dòng)測(cè)試工具對(duì)這類(lèi)測(cè)試尤其有用。
單元測(cè)試——是最小粒度的測(cè)試,以測(cè)試某個(gè)功能或代碼塊。一般由程序員來(lái)做,因?yàn)樗枰纼?nèi)部程序設(shè)計(jì)和編碼的細(xì)節(jié)。
JUnit ——是一個(gè)開(kāi)發(fā)源代碼的Java測(cè)試框架,用于編寫(xiě)和運(yùn)行可重復(fù)的測(cè)試。他是用于單元測(cè)試框架體系xUnit的一個(gè)實(shí)例(用于java語(yǔ)言)。主要用于白盒測(cè)試,回歸測(cè)試。
2、單元測(cè)試概述
2.1、單元測(cè)試的好處
A、提高開(kāi)發(fā)速度——測(cè)試是以自動(dòng)化方式執(zhí)行的,提升了測(cè)試代碼的執(zhí)行效率。
B、提高軟件代碼質(zhì)量——它使用小版本發(fā)布至集成,便于實(shí)現(xiàn)人員除錯(cuò)。同時(shí)引入重構(gòu)概念,讓代碼更干凈和富有彈性。
C、提升系統(tǒng)的可信賴度——它是回歸測(cè)試的一種。支持修復(fù)或更正后的“再測(cè)試”,可確保代碼的正確性。
2.2、單元測(cè)試的針對(duì)對(duì)象
A、面向過(guò)程的軟件開(kāi)發(fā)針對(duì)過(guò)程。
B、面向?qū)ο蟮能浖_(kāi)發(fā)針對(duì)對(duì)象。
C、可以做類(lèi)測(cè)試,功能測(cè)試,接口測(cè)試(最常用于測(cè)試類(lèi)中的方法)。
2.3、單元測(cè)試工具和框架
目前的最流行的單元測(cè)試工具是xUnit系列框架,常用的根據(jù)語(yǔ)言不同分為JUnit(java),CppUnit(C++),DUnit (Delphi ),NUnit(.net),PhpUnit(Php )等等。該測(cè)試框架的第一個(gè)和最杰出的應(yīng)用就是由Erich Gamma (《設(shè)計(jì)模式》的作者)和Kent Beck(XP(Extreme Programming)的創(chuàng)始人 )提供的開(kāi)放源代碼的JUnit。
3.Junit入門(mén)簡(jiǎn)介
3.1、JUnit的好處和JUnit單元測(cè)試編寫(xiě)原則
好處:
A、可以使測(cè)試代碼與產(chǎn)品代碼分開(kāi)。
B、針對(duì)某一個(gè)類(lèi)的測(cè)試代碼通過(guò)較少的改動(dòng)便可以應(yīng)用于另一個(gè)類(lèi)的測(cè)試。
C、易于集成到測(cè)試人員的構(gòu)建過(guò)程中,JUnit和Ant的結(jié)合可以實(shí)施增量開(kāi)發(fā)。
D、JUnit是公開(kāi)源代碼的,可以進(jìn)行二次開(kāi)發(fā)。
C、可以方便地對(duì)JUnit進(jìn)行擴(kuò)展。
編寫(xiě)原則:
A、是簡(jiǎn)化測(cè)試的編寫(xiě),這種簡(jiǎn)化包括測(cè)試框架的學(xué)習(xí)和實(shí)際測(cè)試單元的編寫(xiě)。
B、是使測(cè)試單元保持持久性。
C、是可以利用既有的測(cè)試來(lái)編寫(xiě)相關(guān)的測(cè)試。
3.2、JUnit的特征
A、使用斷言方法判斷期望值和實(shí)際值差異,返回Boolean值。
B、測(cè)試驅(qū)動(dòng)設(shè)備使用共同的初始化變量或者實(shí)例。
C、測(cè)試包結(jié)構(gòu)便于組織和集成運(yùn)行。
D、支持圖型交互模式和文本交互模式。
3.3、JUnit框架組成
A、對(duì)測(cè)試目標(biāo)進(jìn)行測(cè)試的方法與過(guò)程集合,可稱為測(cè)試用例(TestCase)。
B、測(cè)試用例的集合,可容納多個(gè)測(cè)試用例(TestCase),將其稱作測(cè)試包(TestSuite)。
C、測(cè)試結(jié)果的描述與記錄。(TestResult) 。
D、測(cè)試過(guò)程中的事件監(jiān)聽(tīng)者(TestListener)。
E、每一個(gè)測(cè)試方法所發(fā)生的與預(yù)期不一致?tīng)顩r的描述,稱其測(cè)試失敗元素(TestFailure)
F、JUnit Framework中的出錯(cuò)異常(AssertionFailedError)。
JUnit框架是一個(gè)典型的Composite模式:TestSuite可以容納任何派生自Test的對(duì)象;當(dāng)調(diào)用TestSuite對(duì)象的run()方法是,會(huì)遍歷自己容納的對(duì)象,逐個(gè)調(diào)用它們的run()方法。(可參考《程序員》2003-6期)。
3.4、JUnit的安裝和配置
JUnit安裝步驟分解:
在http://download.sourceforge.net/junit/中下載JUnit包并將Junit壓縮包解壓到一個(gè)物理目錄中(例如C:\Junit3.8.1)。
記錄Junit.jar文件所在目錄名(例如C:\Junit3.8.1\Junit.jar)。
進(jìn)入操作系統(tǒng)(以Windows2000操作系統(tǒng)為準(zhǔn)),按照次序點(diǎn)擊“開(kāi)始 設(shè)置 控制面板”。
在控制面板選項(xiàng)中選擇“系統(tǒng)”,點(diǎn)擊“環(huán)境變量”,在“系統(tǒng)變量”的“變量”列表框中選擇“CLASS-PATH”關(guān)鍵字(不區(qū)分大小寫(xiě)),如果該關(guān)鍵字不存在則添加。
雙擊“CLASS-PATH”關(guān)鍵字添加字符串“C:\Junit3.8.1\Junti.jar”(注意,如果已有別的字符串請(qǐng)?jiān)谠撟址淖址Y(jié)尾加上分號(hào)“;”),這樣確定修改后Junit就可以在集成環(huán)境中應(yīng)用了。
對(duì)于IDE環(huán)境,對(duì)于需要用到的JUnit的項(xiàng)目增加到lib中,其設(shè)置不同的IDE有不同的設(shè)置 。
3.5、JUnit中常用的接口和類(lèi)
Test接口——運(yùn)行測(cè)試和收集測(cè)試結(jié)果
Test接口使用了Composite設(shè)計(jì)模式,是單獨(dú)測(cè)試用例 (TestCase),聚合測(cè)試模式(TestSuite)及測(cè)試擴(kuò)展(TestDecorator)的共同接口。
它的public int countTestCases()方法,它來(lái)統(tǒng)計(jì)這次測(cè)試有多少個(gè)TestCase,另外一個(gè)方法就是public void run( TestResult ),TestResult是實(shí)例接受測(cè)試結(jié)果, run方法執(zhí)行本次測(cè)試。
TestCase抽象類(lèi)——定義測(cè)試中固定方法
TestCase是Test接口的抽象實(shí)現(xiàn),(不能被實(shí)例化,只能被繼承)其構(gòu)造函數(shù)TestCase(string name)根據(jù)輸入的測(cè)試名稱name創(chuàng)建一個(gè)測(cè)試實(shí)例。由于每一個(gè)TestCase在創(chuàng)建時(shí)都要有一個(gè)名稱,若某測(cè)試失敗了,便可識(shí)別出是哪個(gè)測(cè)試失敗。
TestCase類(lèi)中包含的setUp()、tearDown()方法。setUp()方法集中初始化測(cè)試所需的所有變量和實(shí)例,并且在依次調(diào)用測(cè)試類(lèi)中的每個(gè)測(cè)試方法之前再次執(zhí)行setUp()方法。tearDown()方法則是在每個(gè)測(cè)試方法之后,釋放測(cè)試程序方法中引用的變量和實(shí)例。
開(kāi)發(fā)人員編寫(xiě)測(cè)試用例時(shí),只需繼承TestCase,來(lái)完成run方法即可,然后JUnit獲得測(cè)試用例,執(zhí)行它的run方法,把測(cè)試結(jié)果記錄在TestResult之中。
Assert靜態(tài)類(lèi)——一系列斷言方法的集合
Assert包含了一組靜態(tài)的測(cè)試方法,用于期望值和實(shí)際值比對(duì)是否正確,即測(cè)試失敗,Assert類(lèi)就會(huì)拋出一個(gè)AssertionFailedError異常,JUnit測(cè)試框架將這種錯(cuò)誤歸入Failes并加以記錄,同時(shí)標(biāo)志為未通過(guò)測(cè)試。如果該類(lèi)方法中指定一個(gè)String類(lèi)型的傳參則該參數(shù)將被做為AssertionFailedError異常的標(biāo)識(shí)信息,告訴測(cè)試人員改異常的詳細(xì)信息。
JUnit 提供了6大類(lèi)31組斷言方法,包括基礎(chǔ)斷言、數(shù)字?jǐn)嘌浴⒆址麛嘌浴⒉紶枖嘌浴?duì)象斷言。
其中assertEquals(Object expcted,Object actual)內(nèi)部邏輯判斷使用equals()方法,這表明斷言兩個(gè)實(shí)例的內(nèi)部哈希值是否相等時(shí),最好使用該方法對(duì)相應(yīng)類(lèi)實(shí)例的值進(jìn)行比較。而assertSame(Object expected,Object actual)內(nèi)部邏輯判斷使用了Java運(yùn)算符“==”,這表明該斷言判斷兩個(gè)實(shí)例是否來(lái)自于同一個(gè)引用(Reference),最好使用該方法對(duì)不同類(lèi)的實(shí)例的值進(jìn)行比對(duì)。asserEquals(String message,String expected,String actual)該方法對(duì)兩個(gè)字符串進(jìn)行邏輯比對(duì),如果不匹配則顯示著兩個(gè)字符串有差異的地方。ComparisonFailure類(lèi)提供兩個(gè)字符串的比對(duì),不匹配則給出詳細(xì)的差異字符。
TestSuite測(cè)試包類(lèi)——多個(gè)測(cè)試的組合
TestSuite類(lèi)負(fù)責(zé)組裝多個(gè)Test Cases。待測(cè)得類(lèi)中可能包括了對(duì)被測(cè)類(lèi)的多個(gè)測(cè)試,而TestSuit負(fù)責(zé)收集這些測(cè)試,使我們可以在一個(gè)測(cè)試中,完成全部的對(duì)被測(cè)類(lèi)的多個(gè)測(cè)試。
TestSuite類(lèi)實(shí)現(xiàn)了Test接口,且可以包含其它的TestSuites。它可以處理加入Test時(shí)的所有拋出的異常。
TestSuite處理測(cè)試用例有6個(gè)規(guī)約(否則會(huì)被拒絕執(zhí)行測(cè)試)
A 測(cè)試用例必須是公有類(lèi)(Public)
B 測(cè)試用例必須繼承與TestCase類(lèi)
C 測(cè)試用例的測(cè)試方法必須是公有的( Public )
D 測(cè)試用例的測(cè)試方法必須被聲明為Void
E 測(cè)試用例中測(cè)試方法的前置名詞必須是test
F 測(cè)試用例中測(cè)試方法誤任何傳遞參數(shù)
n TestResult結(jié)果類(lèi)和其它類(lèi)與接口
TestResult結(jié)果類(lèi)集合了任意測(cè)試?yán)奂咏Y(jié)果,通過(guò)TestResult實(shí)例傳遞個(gè)每個(gè)測(cè)試的Run()方法。TestResult在執(zhí)行TestCase是如果失敗會(huì)異常拋出
TestListener接口是個(gè)事件監(jiān)聽(tīng)規(guī)約,可供TestRunner類(lèi)使用。它通知listener的對(duì)象相關(guān)事件,方法包括測(cè)試開(kāi)始startTest(Test test),測(cè)試結(jié)束endTest(Test test),錯(cuò)誤,增加異常addError(Test test,Throwable t)和增加失敗addFailure(Test test,AssertionFailedError t)
TestFailure失敗類(lèi)是個(gè)“失敗”狀況的收集類(lèi),解釋每次測(cè)試執(zhí)行過(guò)程中出現(xiàn)的異常情況。其toString()方法返回“失敗”狀況的簡(jiǎn)要描述
3.6、JUnit一個(gè)實(shí)例
在控制臺(tái)中簡(jiǎn)單的范例如下:
1、寫(xiě)個(gè)待測(cè)試的Triangle類(lèi),創(chuàng)建一個(gè)TestCase的子類(lèi)ExampleTest:
2、 ExampleTest中寫(xiě)一個(gè)或多個(gè)測(cè)試方法,斷言期望的結(jié)果(注意:以test作為待測(cè)試的方法的開(kāi)頭,這樣這些方法可以被自動(dòng)找到并被測(cè)試)
3、 ExampleTest中寫(xiě)一個(gè)suite()方法,它會(huì)使用反射動(dòng)態(tài)的創(chuàng)建一個(gè)包含所有的testXxxx方法的測(cè)試套件:
4、 ExampleTest可以寫(xiě)setUp()、tearDown()方法,以便于在測(cè)試時(shí)初始化或銷(xiāo)毀測(cè)試所需的所有變量和實(shí)例。(不是必須的)
5、寫(xiě)一個(gè)main()方法以文本運(yùn)行器或其它GUI的方式方便的運(yùn)行測(cè)試
6、編譯ExampleTest,執(zhí)行測(cè)試。
3.7、Eclipse中JUnit的使用
Eclipse自帶了一個(gè)JUnit的插件,不用安裝就可以在你的項(xiàng)目中開(kāi)始測(cè)試相關(guān)的類(lèi),并且可以調(diào)試你的測(cè)試用例和被測(cè)試類(lèi)。
使用步驟如下:
1、新建一個(gè)測(cè)試用例,點(diǎn)擊“File->New->Other…菜單項(xiàng),在彈出的“New”對(duì)話框中選擇”Java->JUnit”,下的TestCase 或TestSuite,就進(jìn)入“New JUnit TestCase”對(duì)話框
2、在“New JUnit TestCase”對(duì)話框填寫(xiě)相應(yīng)的欄目,主要有Name(測(cè)試用例名),SuperClass(測(cè)試的超類(lèi)一般是默認(rèn)的junit.framework.TestCase),Class Under Test(被測(cè)試的類(lèi)),Source Folder(測(cè)試用例保存的目錄),Package(測(cè)試用例包名),及是否自動(dòng)生成main,setUp,tearDown方法。
3、如果點(diǎn)擊下面的”Next>”按鈕,你還可以直接勾選你想測(cè)試的被測(cè)試類(lèi)的方法,Eclipse將自動(dòng)生成與被選方法相應(yīng)的測(cè)試方法,點(diǎn)擊“Fishish”按鈕后一個(gè)測(cè)試用例就創(chuàng)建好了。
4、編寫(xiě)完成你的測(cè)試用例后,點(diǎn)擊“Run”按鈕就可以看到運(yùn)行結(jié)果了。
3.8、JUnit的擴(kuò)展應(yīng)用
以下羅列了些JUnit的擴(kuò)展應(yīng)用:
JUnit + HttpUnit=WEB功能測(cè)試工具
JUnit + hansel =代碼覆蓋測(cè)試工具
JUnit + abbot =界面自動(dòng)回放測(cè)試工具
JUnit + dbunit =數(shù)據(jù)庫(kù)測(cè)試工具
JUnit + junitperf=性能測(cè)試工具
3.9、一些使用JUnit經(jīng)驗(yàn)
不要用TestCase的構(gòu)造函數(shù)初始化,而要用setUp()和tearDown()方法。
不要依賴或假定測(cè)試運(yùn)行的順序,因?yàn)镴Unit利用Vector保存測(cè)試方法。所以不同的平臺(tái)會(huì)按不同的順序從Vector中取出測(cè)試方法。
避免編寫(xiě)有副作用的TestCase。例如:如果隨后的測(cè)試依賴于某些特定的交易數(shù)據(jù),就不要提交交易數(shù)據(jù)。簡(jiǎn)單的回滾就可以了。
當(dāng)繼承一個(gè)測(cè)試類(lèi)時(shí),記得調(diào)用父類(lèi)的setUp()和tearDown()方法。
將測(cè)試代碼和工作代碼放在一起,一邊同步編譯和更新。
測(cè)試類(lèi)和測(cè)試方法應(yīng)該有一致的命名方案。如在工作類(lèi)名前加上test從而形成測(cè)試類(lèi)名。
確保測(cè)試與時(shí)間無(wú)關(guān),不要依賴使用過(guò)期的數(shù)據(jù)進(jìn)行測(cè)試。導(dǎo)致在隨后的維護(hù)過(guò)程中很難重現(xiàn)測(cè)試。
如果你編寫(xiě)的軟件面向國(guó)際市場(chǎng),編寫(xiě)測(cè)試時(shí)要考慮國(guó)際化的因素。不要僅用母語(yǔ)的Locale進(jìn)行測(cè)試。
盡可能地利用JUnit提供地assert/fail方法以及異常處理的方法,可以使代碼更為簡(jiǎn)潔。
測(cè)試要盡可能地小,執(zhí)行速度快。
參考資料與附件
1. http:// www.junit.org JUnit官方網(wǎng)站
2. http://bbs.51cmm.com 的測(cè)試論壇
3. http://www.uml.org.cn 的軟件測(cè)試專欄
4. 單元測(cè)試 《程序員》 2002年7期
5. JUnit設(shè)計(jì)模式分析 《程序員》2003年6期
6. 《軟件測(cè)試和JUnit實(shí)踐》
7. 附件Triangle.java 一個(gè)要測(cè)試的類(lèi)
8. 附件ExampleTest.java 一個(gè)測(cè)試用例類(lèi)
Triangle.java
/**
* this is Triangle class
* @author liujun
*/
public class Triangle
{
//定義三角形的三邊
protected long lborderA = 0;
protected long lborderB = 0;
protected long lborderC = 0;
//構(gòu)造函數(shù)
public Triangle(long lborderA,long lborderB,long lborderC)
{
this.lborderA = lborderA;
this.lborderB = lborderB;
this.lborderC = lborderC;
}
/**
* 判斷是否是三角形
* 是返回ture;不是返回false
*/
public boolean isTriangle(Triangle triangle)
{
boolean isTrue = false;
//判斷邊界,大于0小于200,出界返回false
if((triangle.lborderA>0&&triangle.lborderA<200)
&&(triangle.lborderB>0&&triangle.lborderB<200)
&&(triangle.lborderC>0&&triangle.lborderC<200))
{
//判斷兩邊之和大于第三邊
if((triangle.lborderA<(triangle.lborderB+triangle.lborderC))
&&(triangle.lborderB<(triangle.lborderA+triangle.lborderC))
&&(triangle.lborderC<(triangle.lborderA+triangle.lborderB)))
isTrue = true;
}
return isTrue;
}
/**
* 判斷三角形類(lèi)型
* 等腰三角形返回字符串“等腰三角形”;
* 等邊三角形返回字符串“等邊三角形”;
* 其它三角形返回字符串“不等邊三角形”;
*/
public String isType(Triangle triangle)
{
String strType = "";
// 判斷是否是三角形
if(this.isTriangle(triangle))
{
//判斷是否是等邊三角形 if(triangle.lborderA==triangle.lborderB&&triangle.lborderB==triangle.lborderC)
strType = "等邊三角形";
//判斷是否是不等邊三角形
else if((triangle.lborderA!=triangle.lborderB)&&
(triangle.lborderB!=triangle.lborderC)&&
(triangle.lborderA!=triangle.lborderC))
strType = "不等邊三角形";
else
strType="等腰三角形";
}
return strType;
}
}
ExampleTest.java
import junit.framework.*;
/**
* Some tests.
*
*/
public class ExampleTest extends TestCase {
public Triangle triangle;
//初始化
protected void setUp() {
triangle=new Triangle(10,2,9);
}
public static Test suite() {
return new TestSuite(ExampleTest.class);
}
//函數(shù)isTriangle()的測(cè)試用例
public void testIsTriangle() {
assertTrue(triangle.isTriangle(triangle));
}
//函數(shù)isType()的測(cè)試用例
public void testIsType()
{
assertEquals("這次測(cè)試",triangle.isType(triangle),"不等邊三角形");
}
//執(zhí)行測(cè)試
public static void main (String[] args) {
//文本方式
junit.textui.TestRunner.run(suite());
//Swingui方式
//junit.swingui.TestRunner.run(suite().getClass());
//awtui方式
//junit.awtui.TestRunner.run(suite().getClass());
}
}
posted on 2005-04-07 10:42 辰 閱讀(330) 評(píng)論(0) 編輯 收藏 所屬分類(lèi): 測(cè)試