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

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

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

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

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

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

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

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

    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));
    }

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

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

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