您的位置:軟件測試 > 開源軟件測試 > 開源單元測試工具 > junit
單元測試利器JUnit
作者:網絡轉載 發(fā)布時間:[ 2013/3/29 14:59:08 ] 推薦標簽:

    可是,這種 Fixture 設置方式還是引來了批評,因為它效率低下,特別是在設置 Fixture 非常耗時的情況下(例如設置數據庫鏈接)。而且對于不會發(fā)生變化的測試環(huán)境或者測試數據來說,是不會影響到測試方法的執(zhí)行結果的,也沒有必要針對每一個測試方法重新設置一次 Fixture。因此在 JUnit 4 中引入了類級別的 Fixture 設置方法,編寫規(guī)范如下:

    使用注解 org,junit.BeforeClass 修飾用于初始化 Fixture 的方法。
    使用注解 org.junit.AfterClass 修飾用于注銷 Fixture 的方法。
    保證這兩種方法都使用 public static void 修飾,而且不能帶有任何參數。
類級別的 Fixture 僅會在測試類中所有測試方法執(zhí)行之前執(zhí)行初始化,并在全部測試方法測試完畢之后執(zhí)行注銷方法(圖6)。代碼范本如下:

引用
//類級別Fixture初始化方法
@BeforeClass public static void dbInit(){……}

//類級別Fixture注銷方法
@AfterClass public static void dbClose(){……}

圖6 類級別 Fixture 執(zhí)行示意圖

  異常以及時間測試

    注解 org.junit.Test 中有兩個非常有用的參數:expected 和 timeout。參數 expected 代表測試方法期望拋出指定的異常,如果運行測試并沒有拋出這個異常,則 JUnit 會認為這個測試沒有通過。這為驗證被測試方法在錯誤的情況下是否會拋出預定的異常提供了便利。舉例來說,方法 supportDBChecker 用于檢查用戶使用的數據庫版本是否在系統(tǒng)的支持的范圍之內,如果用戶使用了不被支持的數據庫版本,則會拋出運行時異常 UnsupportedDBVersionException。測試方法 supportDBChecker 在數據庫版本不支持時是否會拋出指定異常的單元測試方法大體如下:

Java代碼 復制代碼

    @Test(expected=UnsupportedDBVersionException.class)  
        public void unsupportedDBCheck(){  
            ……  
    } 

    注解 org.junit.Test 的另一個參數 timeout,指定被測試方法被允許運行的長時間應該是多少,如果測試方法運行時間超過了指定的毫秒數,則JUnit認為測試失敗。這個參數對于性能測試有一定的幫助。例如,如果解析一份自定義的 XML 文檔花費了多于 1 秒的時間,需要重新考慮 XML 結構的設計,那單元測試方法可以這樣來寫:

Java代碼 復制代碼

    @Test(timeout=1000)  
        public void selfXMLReader(){  
            ……  
    } 

  忽略測試方法

    JUnit 提供注解 org.junit.Ignore 用于暫時忽略某個測試方法,因為有時候由于測試環(huán)境受限,并不能保證每一個測試方法都能正確運行。例如下面的代碼便表示由于沒有了數據庫鏈接,提示 JUnit 忽略測試方法 unsupportedDBCheck:

Java代碼 復制代碼

    @ Ignore(“db is down”)  
    @Test(expected=UnsupportedDBVersionException.class)  
        public void unsupportedDBCheck(){  
            ……  
    } 

    但是一定要小心。注解 org.junit.Ignore 只能用于暫時的忽略測試,如果需要永遠忽略這些測試,一定要確認被測試代碼不再需要這些測試方法,以免忽略必要的測試點。

測試運行器

    又一個新概念出現(xiàn)了——測試運行器,JUnit 中所有的測試方法都是由它負責執(zhí)行的。JUnit 為單元測試提供了默認的測試運行器,但 JUnit 并沒有限制您必須使用默認的運行器。相反,您不僅可以定制自己的運行器(所有的運行器都繼承自 org.junit.runner.Runner),而且還可以為每一個測試類指定使用某個具體的運行器。指定方法也很簡單,使用注解 org.junit.runner.RunWith 在測試類上顯式的聲明要使用的運行器即可:

Java代碼 復制代碼

    @RunWith(CustomTestRunner.class)  
    public class TestWordDealUtil {  
    ……  
    } 

  顯而易見,如果測試類沒有顯式的聲明使用哪一個測試運行器,JUnit 會啟動默認的測試運行器執(zhí)行測試類(比如上面提及的單元測試代碼)。一般情況下,默認測試運行器可以應對絕大多數的單元測試要求;當使用 JUnit 提供的一些高級特性(例如即將介紹的兩個特性)或者針對特殊需求定制 JUnit 測試方式時,顯式的聲明測試運行器必不可少了。

測試套件

  在實際項目中,隨著項目進度的開展,單元測試類會越來越多,可是直到現(xiàn)在我們還只會一個一個的單獨運行測試類,這在實際項目實踐中肯定是不可行的。為了解決這個問題,JUnit 提供了一種批量運行測試類的方法,叫做測試套件。這樣,每次需要驗證系統(tǒng)功能正確性時,只執(zhí)行一個或幾個測試套件便可以了。測試套件的寫法非常簡單,您只需要遵循以下規(guī)則:

創(chuàng)建一個空類作為測試套件的入口。
    使用注解 org.junit.runner.RunWith 和org.junit.runners.Suite.SuiteClasses 修飾這個空類。
將 org.junit.runners.Suite 作為參數傳入注解 RunWith,以提示 JUnit 為此類使用套件運行器執(zhí)行。
    將需要放入此測試套件的測試類組成數組作為注解 SuiteClasses 的參數。
    保證這個空類使用 public 修飾,而且存在公開的不帶有任何參數的構造函數。
Java代碼 復制代碼

    package com.ai92.cooljunit;  
     
    import org.junit.runner.RunWith;  
    import org.junit.runners.Suite;  
    ……  
     
    /** 
     * 批量測試 工具包 中測試類 
     * @author Ai92 
     */ 
    @RunWith(Suite.class)  
    @Suite.SuiteClasses({TestWordDealUtil.class})  
    public class RunAllUtilTestsSuite {  
    } 

    上例代碼中,我們將前文提到的測試類 TestWordDealUtil 放入了測試套件 RunAllUtilTestsSuite 中,在 Eclipse 中運行測試套件,可以看到測試類 TestWordDealUtil 被調用執(zhí)行了。測試套件中不僅可以包含基本的測試類,而且可以包含其它的測試套件,這樣可以很方便的分層管理不同模塊的單元測試代碼。但是,您一定要保證測試套件之間沒有循環(huán)包含關系,否則無盡的循環(huán)會出現(xiàn)在您的面前……。

參數化測試

    回顧一下我們在小節(jié)“JUnit 初體驗”中舉的實例。為了保證單元測試的嚴謹性,我們模擬了不同類型的字符串來測試方法的處理能力,為此我們編寫大量的單元測試方法?墒沁@些測試方法都是大同小異:代碼結構都是相同的,不同的僅僅是測試數據和期望值。有沒有更好的方法將測試方法中相同的代碼結構提取出來,提高代碼的重用度,減少復制粘貼代碼的煩惱?在以前的 JUnit 版本上,并沒有好的解決方法,而現(xiàn)在您可以使用 JUnit 提供的參數化測試方式應對這個問題。

上一頁123456下一頁
軟件測試工具 | 聯(lián)系我們 | 投訴建議 | 誠聘英才 | 申請使用列表 | 網站地圖
滬ICP備07036474 2003-2017 版權所有 上海澤眾軟件科技有限公司 Shanghai ZeZhong Software Co.,Ltd