Sung in Blog

                     一些技術(shù)文章 & 一些生活雜碎
          這篇文章將給你介紹JUnit——一個工程測試調(diào)式的工具。 在介紹了了 測試驅(qū)動開發(fā)理論之后,我們繼續(xù)介紹“怎樣用Eclipse創(chuàng)建你的、JUnit Test”。 我們會用象"hello word"一樣簡單例子來向你揭露JUnit Case。
            
            自動化測試(automated testing)在好多書籍中被介紹了,但很少注意講怎樣去組織這些測試。 當(dāng)測試寫的越多時,很難知道把這些測試放到哪或者用什么去調(diào)用它們。 在極限編程---Extreme Programming(xp),測試驅(qū)動開發(fā) Test-Driven Development (TDD)盛行的時代,這成了一個很大的問題。 你可以把 測試驅(qū)動開發(fā)(TDD)認(rèn)為是"Development through testing" 開發(fā)由經(jīng)測試。
            
            TDD的主要條款:
            
            在任何代碼片段之前,必須先寫好自動檢測這段代碼功能的程序。既然代碼不存在,那么測試在一開始就失敗。
            
            在 測試通過之后,復(fù)制的代碼必須刪掉。
            
            象這樣的方式每個程序員都可以應(yīng)用,并不需要特定的方法論。但在我們開始寫test之前, 值得我們注意的是,先考慮一下如何組織自動化測試。
            
            這里有幾種我們需要考慮的測試
            
            單元測試(Unit test) :這些是為檢查個別模塊(比如classes類)服務(wù)的。 如果對象需要訪問外部的數(shù)據(jù)源,比如Database,就需要通過一些模擬的對象(MOCK object)來模擬Database, (但這也只有在真實環(huán)境的數(shù)據(jù)與測試環(huán)境不同的時候。
            比如測試環(huán)境里面沒有真實Datebase,就需要MOCK Object)
            
            用戶測試 (Customer's test):這里是功能的,系統(tǒng)的并且認(rèn)可的測試。系統(tǒng)中所有的行為檢查都做為一個整體。 在XP理論中,這些測試,是由用戶編寫的,給出測試案例提綱。
            
            集成測試 (Itegration tests): 這些測試象是在用戶測試和單元測試之間的十字路口。 集成測試幫助程序測試幾個級別中交互。 ,Mock Object不會出現(xiàn)在集承測試中,他會增加測試時間。同樣,集成測試也經(jīng)常需要存在的特定的測試環(huán)境,比如從數(shù)據(jù)庫中放一些測試數(shù)據(jù)。集成測試也許使用外部的lib。 Cactus就是這樣一個J2EE集成的lib。 解釋這些測試已經(jīng)超出了本篇文章的范圍,并且也需要詳細(xì)的理論敘述,所以,你僅需要知道這種測試存在就可以了。
            
            開發(fā)測試(Developer's test) : 這種測試就是那些開發(fā)者校驗 整段代碼,新加的代碼,新加的函數(shù)函數(shù)。 對于每個開發(fā)而言, 隨時生成新的的測試去檢查代碼是很重要的。 組織這些測試和組織這些代碼有著同樣的重要性。
            
            至于本文其他地方,只要說到"測試",就是專指開發(fā)測試(Developer's test)。
            
            在開發(fā)期間, 一個程序員有時可能問自己:系統(tǒng)中這個行為有test么,這個test存在么,哪里可以找到這個test?每次發(fā)現(xiàn)錯誤,都是靠最基礎(chǔ)修改bug而不是通過自動測試,這是一個典型的例子。 在這種情形下事情進展可能是:
            
            去找到這個函數(shù)的測試(可能測試已經(jīng)寫了,但里面還有一些小錯誤)
            如果這樣的測試還沒有,或者測試不能蓋住這種錯誤,我們就寫一個新的測試來蓋住這種錯誤。
            現(xiàn)在 我們深信,程序在新的測試中不會通過。
            修復(fù)程序中的bug。
            再運行測試
            確定程序在測試中通過了。
            
            當(dāng)然,可能出現(xiàn)各種各樣的處理, 但思想必須很明確:你只需糾正那些被測試找出那些錯誤。
            
            現(xiàn)在,讓我們告訴你一個開發(fā)人員怎樣解決這種情形。 通過存在的功能性的測試
            
            我利用一些集成的開發(fā)環(huán)境(IDE)來查找 被修正那些類和方法的放在什么地方。
            
            制造一個已知的錯誤環(huán)境,來查找那些代碼判斷存在錯誤。
            
            最后但不是最不重要的,寫好測試并且放到一個現(xiàn)有的測試類中去。 如果你不小心出了錯誤, 期望你和你的同事能注意到副本,并且糾正它
            
            都準(zhǔn)就緒,開始建立測試了, 所以現(xiàn)在需要給測試取一個名稱。 你可能說,“這不是問題: 在每個類面前加個Test就是了!” 但并不是那么簡單的, 讓我告訴你這樣如果可能造成的問題:
            
            當(dāng)時候我們在使用TDD的方式開發(fā)時, 需要測試的class或者method可能都不存在。
            
            也可能一個test 含蓋了好幾個方法,甚至好幾個classes。
            
            這些僅僅是最普通的問題, 下面還有更多。
            
            給個在test命名上的建議: test 類的取名首先應(yīng)該表達(dá)出這個類是一個test類,并且能確切的表示出他要檢查哪些,留有這個原class名的味道。 其實這很容易,請別擔(dān)心這個名稱會變的很長或者很丑陋,自己隨便怎樣取都可以。
            
            下面我們將使用Eclipse中的JUnit工具建立我們的第一個測試,假定你已經(jīng)下載了這個產(chǎn)品的當(dāng)前版本, 如果沒有,你隨時可以從它的官方網(wǎng)站(www.eclipse.org)下載。我們需要JUnit,你也可以從它的官方網(wǎng)站(www.junit.org)上下載,下載并解壓縮到你硬盤中存放java libaries的地方。
            
            打開Eclipse.我們將建立一個新的工程的工作空間(workplace project) 點 File -> New ->Project,選擇Java一路Next。 輸入工程名稱(project name),比如ProjectWithJUnit. 點擊完成。 這樣就建立了一個新工程,讓我們配置一下我們的Eclipse,于是,我們把JUnit library 添加到build path. 點擊 Project-->Properties, 選擇Java Build Path Libraries, 點Add Exteranal JARs 選中JUnit.jar。 你將會看到JUnit將會出現(xiàn)在的屏幕上 libraries列表中。 點Okay,Eclipse將強制rebuild所有的build paths.
            
            我們已經(jīng)準(zhǔn)備好,開始寫我們的"Hello World"了 . 讓我們遵照TDD規(guī)范:在編碼之前就建立測試。為了, 我們將假頂我們將要寫的類名是HelloWorld 有一個返回字符串的方法 say().
            
            要建立這樣一個test, 在ProjectWithJUnit標(biāo)題上右鍵, 選擇New -> Other,展開"Java", 選擇JUnit. 在對話框的右邊一攔里選擇TestCase,接著點Next. 參見圖1。
            
            
           

            圖1。 在Eclipse 中建立JUnit test
            在Test class:一攔里輸入我們需要測試的class--HelloWorld。并且給Test case取個名稱--- 比如,TestThatWeGetHelloWorldPrompt(是的,這看上去太長了,但是它能很清楚表達(dá)出它的意思) 點Finish完成。
            
            下面是 TestThatWeGetHelloWorldPrompt.java的代碼:
            
            public class TestThatWeGetHelloWorldPrompt
            
            extends TestCase {
            
            public TestThatWeGetHelloWorldPrompt(
            
            String name) {
            
            super(name);
            
            }
            
            public void testSay() {
            
            HelloWorld hi = new HelloWorld();
            
            assertEquals("Hello World!", hi.say());
            
            }
            
            public static void main(String[] args) {
            
            junit.textui.TestRunner.run(
            
            TestThatWeGetHelloWorldPrompt.class);
            
            }
            
            }
            
            這個代碼一點都不復(fù)雜,僅僅有一點點特別。 不管怎樣,讓我們詳細(xì)的檢查它。 我們繼承了JUnit的TestCase. (TestCase 在JUnit的javadoc里定義是"用來運行多個Test的固定裝置")。 JUnit也定義了TestSuite 由于一組關(guān)聯(lián)的TestCase組成..
            
            通過以下兩步來建立我們簡單的Test Case;
            
            建立Junit.framework.TestCase的實例.
            定義一些 以"test"開頭的測試函數(shù), 并且返回一空值.(比如 testWasTranscationSuccessful(),testShow()等等).
            
            TestThatWeGetHelloWorldPrompt.java 同時遵循這些標(biāo)準(zhǔn): 這些TestCase的子類含有一個testSay()的方法. 這個方法由assertEquals()方法調(diào)用, 用于檢驗say()的返回值(按照這里的做法返回應(yīng)該是不一致,因為一開始建立的HelloWorld 我們讓say()返回的值是null).
            
            main()主函數(shù)是用來運行test并且顯示輸出的結(jié)果. JUnit的TestRunnery以(swing.u)圖形和本文(text.ui)的的方式來執(zhí)行我們的test并反饋信息。我們就使用文本(text.ui),這個Eclipse肯定支持. (譯注:這里可能翻譯的不怎么好,所謂文本和圖形,是指你在建立TestCase的時候,有一個選項,Which method stubs would you like to create,選擇text.ui|| swing.ui||awt.ui,一般是選擇text.ui因為Eclipse肯定支持這個), 依照這些文本的信息,Eclipse同時會生成圖形顯示。(在Package Exploer的下面Tab條上會多個JUnit,點它就看到了:)。
            
            又一個所以,按照現(xiàn)在這樣測試驅(qū)動的開發(fā)的做法, 一旦我們跑起了我們的test,我們應(yīng)該看到返回一些錯誤的信息。 點Run-> Run as -> JUnit Test(注意啊, 這個TestThatWeGetHelloWorldPrompt.java應(yīng)該在Package Explorer被點中,在左邊那個window中),你點到的因該是JUnit window(就是下面的那個Tab條,注意不是Package Exploer),這樣你就看到了JUnit window, 他會顯示一個紅色條,表示是一個失敗的Test。 (如果你按了運行它沒有自動轉(zhuǎn)到這個窗口,你可以點做下Tab條 上的JUnit標(biāo)簽。)
            
           

            一按運行, 太好了,果然出錯了。好,現(xiàn)在正式開始建立用于工作的HelloWorld代碼,---點New->Class,可能和原來的的重復(fù),那就把原來的刪掉。代碼如下:
            
            HelloWolrd.java
            
            public class HelloWorld {
            
            public String say() {
            
            return("Hello World!");
            
            }
            
            }
            
            這及為簡單的,都用不著注釋。現(xiàn)在再來測試一下看看結(jié)果。就用上面的方法,點Run-> Run As Jnit. 在左邊的JUnit窗口中出現(xiàn)了一個綠條。 看圖三。 出現(xiàn)綠色的條表示測試通過了。
            
            
           

            現(xiàn)在,再變個條件,讓測試不通過。 這將幫助我們理解JUnit test怎樣覆蓋并且報出不同的錯誤。 編輯 assertEquals()方法,把它的返回值從"Hello World!"變成另外一個值 比如"Hello ME!". 這樣,當(dāng)你再運行這個JUnit test,那個顯示條又變成紅的了,并且在Failuer Trace里看到是不是什么導(dǎo)致了錯誤。 如圖:
            
            

            總結(jié)。我想說一些自己的想法(這里還是原文不是翻譯過來的)。 我過去并不認(rèn)為測試代碼是開發(fā)過程中很重要的一部分。 但在最近幾年發(fā)展的很快,多虧了那些方法論(比如基于異常開發(fā)"exceptions-based development"等),他們促進了測試以及測試工具的發(fā)展。
          posted on 2005-11-02 15:19 Sung 閱讀(261) 評論(0)  編輯  收藏 所屬分類: Eclipse
          主站蜘蛛池模板: 东乡县| 蓬安县| 辽中县| 都兰县| 青河县| 铁岭市| 贡嘎县| 伊吾县| 墨竹工卡县| 商洛市| 札达县| 宜章县| 柯坪县| 尼木县| 固始县| 包头市| 时尚| 桃源县| 沁水县| 天全县| 沁阳市| 应用必备| 汝城县| 万源市| 芮城县| 长兴县| 四川省| 乐都县| 射阳县| 衡东县| 内江市| 同仁县| 中西区| 大港区| 巴青县| 会泽县| 那坡县| 洪湖市| 济宁市| 许昌市| 东乌珠穆沁旗|