您的位置:軟件測試 > 開源軟件測試 > 開源單元測試工具 > junit
使用JUnit高效完成功能測試
作者:網絡轉載 發(fā)布時間:[ 2013/2/5 15:33:00 ] 推薦標簽:

        功能測試或集成測試是關系到整體系統(tǒng)功能的測試,而不只是牽涉到小段代碼(單元)。這需要將已經單獨測試好的模塊組裝起來,以保證其連接時也能像預期一樣正常工作。JUnit是進行Java程序測試常用的測試框架。

        大多數Java開發(fā)人員都善于解決邏輯結構測試問題,比如如何建立測試預設環(huán)境、利用斷言?添加測試方法、用setup方法進行初始化等。然而,如果Java開發(fā)人員能更深入地了解如何設計功能測試集來有效地檢驗代碼是否正常運行,他們將獲得更多的益處。
        這篇文章介紹了可以建立有效JUnit功能測試集的策略。包括:

        確定測試用例覆蓋所有程序行為。
        確定代碼入口點:測試程序整體功能的主要代碼段。
        匹配入口點與相應的測試用例。
        根據初始化/運行/檢查流程創(chuàng)建測試用例。
        設計并利用運行時事件表進行測試。
        我將結合Saxon(一個可以處理XPath、XQuery和XSLT的XML工具)的源代碼來具體闡述這些策略。Saxon由約50000行Java代碼組成,它是開源的,代碼風格優(yōu)良,注釋文檔詳盡。

確定用例
 
        功能測試有兩個相輔的目標:覆蓋率與粒度。為確保完整性,功能測試必須覆蓋程序提供的所有功能,且必須在各組件水平上分別進行測試。一個測試可以建立在另一個測試的基礎上,但任何測試都不能用來驗證兩項功能。
        建立一個全面的功能測試集,第一步是列出程序可以實現的所有行為。這可以通過使用特定的用例模擬外部因素(程序使用者或其它軟組件)執(zhí)行系統(tǒng)內部的功能來實現。
        一個典型的企業(yè)Java程序應該包含各種用戶所需的詳細文檔,包括用例說明、非功能性要求、測試用例說明、用戶界面設計文檔、模型、用戶個人信息以及其它各種人工生成的信息。一般來說簡單的應用程序只有一個簡單的說明文檔。
        借助這些文檔,你可以快速確定需要測試的用例。每個測試用例都描述了應用程序可以執(zhí)行的一項功能。用規(guī)模相近的測試方案確定的功能是一個好習慣,而較大的方案可以根據其檢驗的功能拆分為較小的方案。

        有許多種建立用例模型的方法,其中簡單的便是輸入/輸出匹配法。在Saxon的query類中,簡單的用例是傳送一個查詢文件、一個查詢請求和一個輸出文件路徑。輸出文件若不存在,將根據要求創(chuàng)建,并在文件中顯示查詢結果。
        更復雜的用例可能需要輸入更多的信息或輸出更多的結果。然而,用例并不關心功能是如何在內部實現的。對它們來說,軟件像是一個“黑盒子”,只要運行正常,即使真正實現軟件功能的是盒子里的侏儒也無所謂。這是很重要的一點,因為輸入/輸出匹配用例很容易直接轉換為測試用例,使得復雜的說明與簡單的測試吻合,確定該運行的功能正常運行,而不該運行的功能如預期一樣失效。
        如果類相對比較簡單,或者已有列舉類所有功能的說明文檔,為指定入口點描述用例將很容易。如果不是這樣,或許需要研究類可能有的所有行為(確定類的目的與用法)。如果你想知道所有調用代碼的地方,也可以從代碼中提取用例。
        可能的情況是,根據開發(fā)人員提供的類的一些基本說明文檔,可以完全確定這些類應有和不應有的行為;诖,設計一套準確的用例集。

轉換測試用例
 
        每個測試用例都由兩部分組成:輸入和預期輸出。輸入部分包括所有創(chuàng)建變量或為變量賦值的測試用例語句。預期輸出部分則表明應該得到的輸出結果,它應該顯示斷言成立或“沒有異常”(不存在斷言語句時)這樣的信息。
        基本的輸入/輸出模式是理解測試用例模型簡單易用的辦法。它采用一般函數(傳遞參數,獲取返回值)和大多數用戶行為(按某個鍵實現某項功能)慣用的模式。然后,可以用該模式進行:

        初始化:建立測試預設環(huán)境。代碼初始化可以在測試開始時進行或通過調用setUp()方法實現。
        運行:調用被測試的代碼,記錄所有值得注意的輸出和數據。
        檢查:使用斷言語句確保代碼正常運行。
        舉例來說,假設要測試Saxon庫的轉換類入口點。其中一個用例是將XML文件轉換為HTML文件,當然前提是已有描述這個轉換的XSL文件。輸入這三個文件的路徑,應該輸出HTML文件的內容。這可以直接轉為下面的測試:

    public void testXSLTransformation() {
      /* initialize the variables
        (or do this in setUp if used in many tests) */
      String processMePath = "/path/to/file.xml";
      String stylesheetPath = "/path/to/stylesheet.xsl";
      String outputFilePath = "/path/to/output.xml";
      //do the work
      Transform.main(new String[] {
        processMePath,
        stylesheetPath,
        "-o", outputFilePath } );
      //check the work
      assertTrue(checkOutputFile(outputFilePath));
    }

        每一步都可以根據需要進行增減。這里聲明的變量也可以簡單地通過調用方法來賦值。預期輸出的實現是由幾個步驟組成。如果成功得到預期輸出,有時可以省略檢查步驟。
        雖然這個模式簡單且靈活可變,但是第二步必不可少。這個模板沒有告訴我們尋找要測試代碼的方法,也不能保證代碼以方便測試的方式運行。這是個需要認真考慮的問題。

功能測試
 
        通過確定執(zhí)行程序功能的主要代碼段,可以將測試建立在一個更有效的環(huán)境下。由于這些類提供了從系統(tǒng)外部進行測試的途徑,所以也是代碼的入口點。
        因此,功能測試的整體目標是確定一組可以訪問系統(tǒng)功能的高層接口類。這些類的獨立性越高越好。畢竟,如果能將類從環(huán)境中分離出來,測試起來會更加容易。
        確定作為入口點的代碼是一個簡單的過程。在代碼庫中,通常有幾個控制該庫所有功能的入口點。這些外部類作為客戶端代碼,與庫的中介對象將開發(fā)人員從復雜的代碼分析中解脫出來。這些便是應當首先對其方法進行測試的類。
        比如,Saxon有一小組類作為邏輯入口點提供對庫的訪問。通過對外部類進行編碼操作,比如轉換、設置和查詢,客戶端代碼可以訪問庫的許多功能類,而無需考慮類的接口問題,甚至無需擔心這些類是否存在。這些外部類用高層易用的接口提供一個簡單的方式對系統(tǒng)功能進行測試,這正是一個優(yōu)良的庫的特征。
        程序代碼中的各個功能模塊通常是各自獨立的。在某些代碼中,甚至可以認為這些模塊各自對應不同的、可通過大量外部類訪問的庫。這些類查找高層接口的邏輯位置。插件結構通常都采用這種設計模式:每個插件程序都有一個可以有效執(zhí)行內部代碼全部功能的簡單接口。
        在一些非嚴格描述的系統(tǒng)中,通常有一個所有程序行為的中介點。在MVC架構中,這個中介類一般作為“控制器”,負責配置系統(tǒng)各部分的請求路由。整體系統(tǒng)的功能主要由這個控制器連接的類實現,因此,這些類是測試的主要對象。
        比如在Applet程序設計中,java.applet.Applet的派生類是所有代碼的中心處理單元。根據代碼的分解程度,測試焦點可以放在Applet子類或與其連接的類上。
        連接各個模塊的代碼也是測試的主要對象。將應用程序請求轉換為數據庫查詢的類,以及有相似功能的適配類是其次應該考慮的測試對象。
        各種基于MVC(模式-視圖-控制器)架構的組件可以用其它的測試框架(比如Junit的擴展)進行測試。例如,Struts的action類好使用JUnit的擴展StrutsTestCase進行測試;服務器端的組件(如Servlets、JSP和EJB)好用Catus進行測試;而HttpUnit則是對Web應用程序進行黑盒測試的好框架。本文討論的所有技術都可應用于這些框架環(huán)境下的測試。

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