电竞比分网-中国电竞赛事及体育赛事平台

分享

eclipse3.2中配置junit(轉(zhuǎn)載自網(wǎng)上)

 zhanghuan 2007-07-23
JUnit學(xué)習(xí)筆記(2007版)
 
一、簡(jiǎn)介
    JUnit是一款由Erich Gamma(《設(shè)計(jì)模式》的作者)和Kent Beck(極限編程的提出者)編寫的開(kāi)源的回歸測(cè)試框架,供Java編碼人員做單元測(cè)試之用。當(dāng)前版本4.1,可以從www.junit.org網(wǎng)站上獲得。與早期的JUnit 3相比,JUnit 4.1依賴于Java 5.0的新特性,因此無(wú)法兼容于jdk 1.4,可以說(shuō)是一個(gè)全新的框架。
    由于這里使用的IDE是Eclipse 3.2.1加語(yǔ)言包,已經(jīng)集成了junit 4.1,因此便免去下載和配置類庫(kù)的麻煩了^_^
二、創(chuàng)建項(xiàng)目
    下面打開(kāi)Eclipse,點(diǎn)擊菜單“文件”->“新建”->“項(xiàng)目”或“新建”按鈕,打開(kāi)“新建”對(duì)話框:
請(qǐng)選中“Java項(xiàng)目”,點(diǎn)擊“下一步”,進(jìn)入“新建Java項(xiàng)目”對(duì)話框:
在這個(gè)對(duì)話框中需要設(shè)置項(xiàng)目的名稱以及項(xiàng)目所在目錄,我為自己的項(xiàng)目起名為JUnitTest,目錄為F:\YPJCCK\JUnit\Eclipse\JUnitTest。由于Eclipse自帶了JUnit類庫(kù),因此此時(shí)點(diǎn)擊“完成”即可。
三、編寫用于測(cè)試的JavaBean
    用于測(cè)試的JavaBean很簡(jiǎn)單,名為Book,只有id和name兩個(gè)屬性,這兩個(gè)屬性將分別用于兩個(gè)用例當(dāng)中。下面開(kāi)始編寫該JavaBean。
    請(qǐng)點(diǎn)擊“文件”->“新建”->“類”,打開(kāi)“新建Java類”對(duì)話框,設(shè)置包為net.test.unit.junit,名稱為Book,并確保“public static void main(String[] args)”選項(xiàng)沒(méi)有選中,然后點(diǎn)擊“完成”。修改代碼如下:
package net.test.unit.junit;
    
public class Book {
    
        private String id = null;
        private String name = null;
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        publicvoid setName(String name) {
            this.name = name;
        }
    
}
至此,用于測(cè)試的JavaBean編寫完成。
四、編寫測(cè)試用例
    這里只用了一個(gè)類進(jìn)行測(cè)試,名為BookTest。以前像這樣的類是需要繼承junit.framework.TestCase的,但由于JUnit 4.1充分利用了Java 5.0新增的注解功能,因此便無(wú)須再這樣做了。當(dāng)然,JUnit 4.1仍然提供對(duì)舊方式的支持,不過(guò)這里并不打算介紹。
    BookTest類包含兩個(gè)用例,分別對(duì)應(yīng)該類的caseId和caseName方法,即每個(gè)方法實(shí)現(xiàn)一個(gè)用例。與JUnit 3.8.1不同,在JUnit 4.1中不再?gòu)?qiáng)制要求方法名以test開(kāi)頭,而是允許隨意命名,只要符合Java的命名規(guī)范就行,這里為了表明這點(diǎn),特意用了case開(kāi)頭,但測(cè)試用例必須以@Test注解。此外,BookTest還有setUp和tearDown這兩個(gè)方法,并分別使用@Before和@After來(lái)進(jìn)行注解,前者在每個(gè)測(cè)試方法開(kāi)始之前執(zhí)行,多用來(lái)做初始化;后者在每個(gè)測(cè)試方法完成之后執(zhí)行,多用來(lái)清理資源。注意,這兩個(gè)方法的命名同樣沒(méi)有限制,且定義的數(shù)量也沒(méi)有限制,只是必須用@Before和@After進(jìn)行注解。另外,JUnit 4.1還提供了@BeforeClass和@AfterClass注解,功能與@Before和@After類似,但前者是用在所有用例執(zhí)行之前做初始化、之后做清理,而后者是在每個(gè)用例執(zhí)行之前做初始化、之后做清理。下面開(kāi)始編寫B(tài)ookTest。
    在Eclipse中,創(chuàng)建BookTest類有兩種方法:方法一,像前邊創(chuàng)建Book類一樣,點(diǎn)擊“文件”->“新建”->“類”來(lái)創(chuàng)建;方法二,先在“包資源管理器”中選中Book類,然后點(diǎn)擊“文件”->“新建”->“JUnit測(cè)試用例”,打開(kāi)“新建JUint測(cè)試用例”窗口:
此時(shí)會(huì)發(fā)現(xiàn),很多信息已經(jīng)被Eclipse自動(dòng)添加進(jìn)來(lái)了。如果想利用Eclipse自動(dòng)創(chuàng)建測(cè)試方法,請(qǐng)點(diǎn)擊“下一步”。由于本文會(huì)自行編寫測(cè)試方法,因此請(qǐng)直接點(diǎn)擊“完成”。
    創(chuàng)建BookTest類后,修改代碼如下:
package net.test.unit.junit;
    
import static org.junit.Assert.*;
    
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
    
public class BookTest {
    
        Book book = null;
    
        @Before
        public void setUp() throws Exception {
            System.out.println("測(cè)試開(kāi)始!");
            book = new Book();
            System.out.println("book對(duì)象被初始化!");
        }
    
        @After
        public void tearDown() throws Exception {
            System.out.println("book對(duì)象將被清理!");
            book = null;
            System.out.println("測(cè)試結(jié)束!");
        }
    
        @Test
        public void caseId() {
            book.setId("001"); //設(shè)置id屬性的值為001
            //使用Assert查看id屬性的值是否為001
            assertEquals("001", book.getId());
            System.out.println("id屬性被測(cè)試!");
        }
    
        @Test
        public void caseName() {
            book.setName("ASP"); //設(shè)置name屬性的值為ASP
            //使用Assert查看name屬性的值是否為JSP,這是個(gè)必然出現(xiàn)錯(cuò)誤的測(cè)試
            assertEquals("JSP", book.getName());
            System.out.println("name屬性被測(cè)試!");
        }
        
}
這里setUp和tearDown方法沒(méi)什么好說(shuō)的,就是執(zhí)行了對(duì)book對(duì)象的初始化和清理,不過(guò)caseId和caseName需要說(shuō)明一下。前者是在對(duì)book的id屬性進(jìn)行測(cè)試,首先賦值為”001”,然后使用assertEquals方法查看id屬性中存放的值是否是期待的值,由于我的期待值也是”001”,所以執(zhí)行后這個(gè)用例應(yīng)該是成功的;后者則是對(duì)book的name屬性進(jìn)行測(cè)試,也是首先賦值為”ASP”,然后使用assertEquals方法查看其值是否是期待的,由于我特意將期待值設(shè)定為根本不可能的”JSP”,因此這個(gè)用例執(zhí)行后會(huì)出現(xiàn)一個(gè)錯(cuò)誤。
關(guān)于assertEquals方法,是Assert類的一個(gè)靜態(tài)方法。在程序開(kāi)頭有這樣一行代碼,“import static org.junit.Assert.*;”,利用了Java 5.0提供的靜態(tài)導(dǎo)入將Assert類靜態(tài)導(dǎo)入,因此我們?cè)诔绦蛑锌梢灾苯邮褂肁ssert類的任何靜態(tài)方法。下面簡(jiǎn)單介紹一下靜態(tài)類org.junit.Assert。
該類主要包含8類22個(gè)方法,如下:
    1.a(chǎn)ssertEquals(),8個(gè)重載,用來(lái)查看對(duì)象中存的值是否是期待的值,與字符串比較中使用的equals()方法類似;
    2.a(chǎn)ssertFalse()和assertTrue(),各2個(gè)重載,用來(lái)查看變量是是否為false或true,如果assertFalse()查看的變量的值是false則測(cè)試成功,如果是true則失敗,assertTrue()與之相反;
    3.a(chǎn)ssertSame()和assertNotSame(),各2個(gè)重載,用來(lái)比較兩個(gè)對(duì)象的引用是否相等和不相等,類似于通過(guò)“==”和“!=”比較兩個(gè)對(duì)象;
    4.a(chǎn)ssertNull()和assertNotNull(),各2個(gè)重載,用來(lái)查看對(duì)象是否為空和不為空;
    5.fail (),2個(gè)重載,意為失敗,用來(lái)拋出錯(cuò)誤。我個(gè)人認(rèn)為有兩個(gè)用途:首先是在測(cè)試驅(qū)動(dòng)開(kāi)發(fā)中,由于測(cè)試用例都是在被測(cè)試的類之前編寫,而寫成時(shí)又不清楚其正確與否,此時(shí)就可以使用fail方法拋出錯(cuò)誤進(jìn)行模擬;其次是拋出意外的錯(cuò)誤,比如要測(cè)試的內(nèi)容是從數(shù)據(jù)庫(kù)中讀取的數(shù)據(jù)是否正確,而導(dǎo)致錯(cuò)誤的原因卻是數(shù)據(jù)庫(kù)連接失敗。
五、運(yùn)行BookTest
    編寫好BookTest后,就可以運(yùn)行了。請(qǐng)點(diǎn)擊運(yùn)行按鈕旁邊的倒三角,選擇“運(yùn)行為”->“1 JUnit測(cè)試”,此時(shí)運(yùn)行效果如下圖:
在圖片的左側(cè)可以看到“JUnit”一欄,而且里邊還有一個(gè)錯(cuò)誤。不過(guò)這個(gè)錯(cuò)誤是預(yù)計(jì)之內(nèi)的,如果不想看到,可以將testName()方法中的”JSP”改成”ASP”,此時(shí)的運(yùn)行效果如下圖:
此時(shí)您會(huì)看到,“JUnit”欄中的進(jìn)度條已不是紅色,而是綠色的,這說(shuō)明已經(jīng)沒(méi)有錯(cuò)誤了。
六、測(cè)試套件
    當(dāng)有多個(gè)測(cè)試類需要同時(shí)進(jìn)行測(cè)試時(shí),應(yīng)使用測(cè)試套件來(lái)完成該工作。但Eclipse 3.2.1所提供的測(cè)試套件創(chuàng)建功能無(wú)法很好地支持JUnit 4.1,所以我們只能手工來(lái)創(chuàng)建了。
    點(diǎn)擊“文件”->“新建”->“類”創(chuàng)建一個(gè)類,類名為AllTests,如下圖:
點(diǎn)擊“完成”,修改代碼如下:
package net.test.unit.junit;
    
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
    
@RunWith(Suite.class)
@Suite.SuiteClasses(BookTest.class)
public class AllTests {}
這里空類AllTests使用@RunWith和@Suite.SuiteClasses進(jìn)行注解,以作為測(cè)試程序入口。將要測(cè)試的類BookTest作為@Suite.SuiteClasses注解的參數(shù),然后將測(cè)試套件Suite作為參數(shù)設(shè)置給運(yùn)行器@RunWith。下面就可以選中該文件,點(diǎn)擊“運(yùn)行為”->“1 JUnit測(cè)試”了。
    這里注意一點(diǎn),@Suite.SuiteClasses注解支持?jǐn)?shù)組,例如:
        @Suite.SuiteClasses ({BookTest.class, BookTest2.class })
這樣就可以一次運(yùn)行多個(gè)測(cè)試類了。
七、命令行下
    前邊介紹的運(yùn)行方式都是基于Eclipse的,其實(shí)JUnit自身也提供了辦法,可以在命令行下執(zhí)行如下命令:
    java -cp junit-4.1.jar所在文件夾; org.junit.runner.JUnitCore
net.test.unit.junit.AllTests
如果要運(yùn)行多個(gè)測(cè)試類,如下:
    java -cp junit-4.1.jar所在文件夾; org.junit.runner.JUnitCore
net.test.unit.junit.AllTests net.test.unit.BookTest
八、JUnit使用進(jìn)階
    @Ignore注解,忽略測(cè)試,用于忽略暫時(shí)不想運(yùn)行的測(cè)試用例。以BookTest為例,在文件頭部添加引用“import org.junit.Ignore;”,然后修改caseName方法:
@Ignore
@Test
    public void caseName()
點(diǎn)擊“運(yùn)行為”->“1 JUnit測(cè)試”,運(yùn)行效果如下:
此時(shí)caseName()方法已經(jīng)被忽略了。
    @Test注解的expected參數(shù),異常測(cè)試,用于測(cè)試是否會(huì)拋出指定的異常,若拋出則為成功,反之為失敗。請(qǐng)?jiān)贐ookTest中新增一個(gè)測(cè)試用例:
    @Test(expected = ArithmeticException.class)
    public void caseException() {
        int n = 2 / 0;
    }
這個(gè)測(cè)試用例是以0為除數(shù),運(yùn)行效果如下:
成功!因?yàn)橹付ǖ腁rithmeticException異常被拋出了。
    @Test注解的timeout參數(shù),限時(shí)測(cè)試,用于限定測(cè)試用例耗費(fèi)的時(shí)間,單位毫秒,如果測(cè)試用例沒(méi)有在限定時(shí)間內(nèi)完成則為失敗,否則以測(cè)試用例的執(zhí)行結(jié)果為準(zhǔn)。請(qǐng)?jiān)贐ookTest中新增一個(gè)測(cè)試用例:
@Test(timeout=1000)
    public void caseWhile() {
        for (;;) {
        }
}
這是一個(gè)死循環(huán),1秒之后將被強(qiáng)制停止,運(yùn)行效果如下:
由于超時(shí),運(yùn)行失敗。
    @Parameters注解,參數(shù)化測(cè)試,用于對(duì)同一測(cè)試用例測(cè)試一組數(shù)據(jù)。請(qǐng)新建一個(gè)“JUnit測(cè)試用例”BookTest2,修改代碼如下:
package net.test.unit.junit;
   
import static org.junit.Assert.assertEquals;
   
import java.util.Arrays;
import java.util.Collection;
   
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
   
@RunWith(Parameterized.class)
public class BookTest2 {
   
        private String expectedId;
        private String targetId;
        private String expectedName;
        private String targetName;
   
        Book book = null;
   
        @Parameters
        public static Collection Result() {
            return Arrays.asList(new Object[][] {
                { "002", "001", "JSP", "ASP" },
                { "001", "001", "ASP", "ASP" }
                });
        }
   
        public BookTest2(String expectedId, String targetId, String expectedName, String targetName) {
            this.expectedId = expectedId;
            this.targetId = targetId;
            this.expectedName = expectedName;
            this.targetName = targetName;
        }
   
        @Before
        public void setUp() throws Exception {
            System.out.println("測(cè)試開(kāi)始!");
             book = new Book();
             System.out.println("book對(duì)象被初始化!");
        }
   
        @After
        public void tearDown() throws Exception {
            System.out.println("book對(duì)象將被清理!");
             book = null;
             System.out.println("測(cè)試結(jié)束!");
        }
   
        @Test
        public void caseId() {
            book.setId(targetId); //設(shè)置id屬性的值
             //使用Assert查看id屬性的值
             assertEquals(expectedId, book.getId());
             System.out.println("id屬性被測(cè)試!");
        }
   
        @Test
        public void caseNames() {
            book.setName(targetName); //設(shè)置name屬性的值
             //使用Assert查看name屬性的值
             assertEquals(expectedName, book.getName());
             System.out.println("name屬性被測(cè)試!");
        }
}
這個(gè)例子其實(shí)就是BookTest的擴(kuò)展版,但在原基礎(chǔ)上有幾點(diǎn)變化:
首先是文件頭部增加了一行代碼:@RunWith(Parameterized.class),用來(lái)調(diào)用BookTest2類運(yùn)行;
其次是定義了一個(gè)用@Parameters注解的Result靜態(tài)方法,該方法用來(lái)存放測(cè)試數(shù)據(jù),本例存放了2組數(shù)據(jù),每組4個(gè);
再次是定義了一個(gè)帶參數(shù)的構(gòu)造函數(shù),其參數(shù)個(gè)數(shù)與每組測(cè)試數(shù)據(jù)的個(gè)數(shù)相等;
    最后是定義了expectedId等4個(gè)成員變量,用來(lái)傳遞測(cè)試數(shù)據(jù)到測(cè)試用例中。
下面執(zhí)行BookTest2,運(yùn)行效果如下:
測(cè)試用例運(yùn)行了兩遍,第一遍由于期待值和設(shè)定值不相等而失敗,第二遍則運(yùn)行成功。
    junit.framework.JUnit4TestAdapter類。依賴于Java 5.0新特性,開(kāi)發(fā)測(cè)試用例無(wú)需繼承junit.framework.TestCase的JUnit 4.1已經(jīng)推出一段時(shí)間了,但有些自帶JUnit測(cè)試環(huán)境的IDE,例如NetBeans 5.5甚至舊版Eclipse仍只支持JUnit 3,無(wú)法正確運(yùn)行基于JUnit 4.1環(huán)境開(kāi)發(fā)的測(cè)試用例,因此要解決這個(gè)問(wèn)題,需要借助于junit.framework.JUnit4TestAdapter類。新建類TestSuite,修改代碼如下:
package net.test.unit.junit;
   
public class TestSuite {
   
        public staticvoid main(String[] args) {
            junit.textui.TestRunner.run(TestSuite.suite());
        }
   
        public static junit.framework.Test suite() {
            return new junit.framework.JUnit4TestAdapter(AllTests.class);   
        }
}
其中最重要的是suite方法,該方法通過(guò)junit.framework.JUnit4TestAdapter類使基于JUnit 4環(huán)境創(chuàng)建的AllTests類能夠運(yùn)行于JUnit 3命令行環(huán)境下。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多