• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
    • 軟件測試技術
    • 軟件測試博客
    • 軟件測試視頻
    • 開源軟件測試技術
    • 軟件測試論壇
    • 軟件測試沙龍
    • 軟件測試資料下載
    • 軟件測試雜志
    • 軟件測試人才招聘
      暫時沒有公告

    字號: | 推薦給好友 上一篇 | 下一篇

    JUnit源碼分析(三)

    發布: 2007-7-01 18:47 | 作者: admin | 來源: | 查看: 39次 | 進入軟件測試論壇討論

    領測軟件測試網
    三、微觀——執行流程與代碼風格











    來過一遍JUnit的執行流程吧,這樣你就能對JUnit有個清晰的認識,雖然作為一個使用者這完全是不必要的。從《JUnit in Action》直接拿來一張JUnit流程圖。



    哦,也許你看暈了,我來當下導游好了。上面已經提到了TestRunner是BaseTestRunner的子類,在三個不同的ui包中各有一個TestRunner。這里我們僅以junit.textui包中的為例。











    TestRunner作為入口程序是怎么被啟動的呢?習慣了使用容器的我們現在也許很少考慮這個問題。那我們在TestRunner類里面找找吧,你看,你發現了這個:











    public static void main(String args[]) {











    這不是我們寫小桌面程序時經常打交道的main方法么?對,就這么簡單。











    從這個main方法入口,首先JUnit將要分析命令行的參數,然后將檢查測試類是否包含符合標準的suite方法,如果有就將執行方法中的內容(見圖中0、1部分);如果沒有找到將自動生成一個TestSuite,這樣就跳過了圖中的0部分,并將測試用例類作為參數傳入(見圖中1部分)。











    上面得到了一個TestSuite類型的對象,現在就可以運行測試了,不過在運行前要先加載TestResult和TestListener的對象(見圖中2部分),用來監聽和記錄測試結果信息。剩下的在圖中可以很容易的看懂了,你可以參照源碼瀏覽一遍。 



    這里提出我的一點疑問。注意到JUnit實踐中提示將測試類中每個測試方法公用的初始化步驟放到setup方法中。這似乎會給你一種錯覺,那就是你會認為setup與tearDown中的語句對于一個測試類中的所有測試方法只會運行一次。但是實際上JUnit在實現上卻出乎意料,setup對于測試類中的每個測試方法都回運行一遍。意思就是說,你把公用的初始化代碼放到setup方法中僅僅是在代碼結構上實現了重用,而沒有起到任何優化系統的作用。比如你在setUp中初始化數據庫連接,那么這個過程將被執行不只一次,這可有點……。我們來看下代碼:











    //theClass為得到的TestCase類,name為此類其中的一個方法











    static public Test createTest(Class theClass, String name) {











           Constructor constructor;











           try {











                  constructor= getTestConstructor(theClass);











           ……











           Object test;











           try {











    //以下內容為獲得一個TestCase對象,并將方法名稱傳入這個對象











                  if (constructor.getParameterTypes().length == 0) {











                         test= constructor.newInstance(new Object[0]);











                         if (test instanceof TestCase)











                                ((TestCase) test).setName(name);











                  } else {











                         test= constructor.newInstance(new Object[]{name});











                  }











           ……











           //返回這個對象











           return (Test) test;











    }











    再看下運行處的代碼,下面的方法是運行在setUp和tearDown中間的











    protected void runTest() throws Throwable {











           //fName就是testcase對象所擁有的那個方法的名稱











           assertNotNull(fName);











           Method runMethod= null;











           try {











                  //根據方法名由反射得到方法











                  runMethod= getClass().getMethod(fName, null);











           }











           ……











                  //執行測試方法











                  runMethod.invoke(this, new Class[0]);











    ……











           }











    這樣每執行一個測試方法就要運行一遍setUp和tearDown方法,大概就是這樣一個過程:



    恩……,也許這是為了兼容老的版本,也許是……。還好,JUnit提供了一個補救的擴展類,那就是我們上面提到的TestSetup,在這里類里面真正的實現了setUp、tearDown方法的提取使用。你在使用的時候,通過繼承來實現自己的setUp、tearDown方法,并使用裝飾模式獨有的調用方式來使用它就可以了。 



    在閱讀的過程中,代碼風格上給我最明顯的感覺就是,代碼基本上全多做到了細化,將每個功能點單獨提取到一個方法中,這樣提高了代碼的可復用性?墒窃陂喿x的時候,在方法間頻繁的跳躍,實在不是件好事,如果沒有IDE的幫助,我非要暈掉不可。











    因此我認為在提高代碼重用上還是要堅持這樣的一條原則:到必要的時候再下手。就是說,在你剛開始寫代碼的時候不要考慮什么重用和擴展,只有當你真正需要復用某段代碼或者擴展系統時,在動手吧(記得在某位牛人的書上是這么來比喻的:讓第一顆子彈打中你)。











    JUnit中使用的是老版本java collection,這大概是因為JUnit最初版本出現的時候還沒有新版collection推出。這種代碼不應該出現在我們現在編寫的代碼中了,請注意。












     四、總結








     四、總結









     四、總結










        好了,基本上分析完了JUnit的代碼,不知道你學到了什么。希望本文能夠起到拋磚引玉的作用。

    延伸閱讀

    文章來源于領測軟件測試網 http://www.kjueaiud.com/


    關于領測軟件測試網 | 領測軟件測試網合作伙伴 | 廣告服務 | 投稿指南 | 聯系我們 | 網站地圖 | 友情鏈接
    版權所有(C) 2003-2010 TestAge(領測軟件測試網)|領測國際科技(北京)有限公司|軟件測試工程師培訓網 All Rights Reserved
    北京市海淀區中關村南大街9號北京理工科技大廈1402室 京ICP備10010545號-5
    技術支持和業務聯系:info@testage.com.cn 電話:010-51297073

    軟件測試 | 領測國際ISTQBISTQB官網TMMiTMMi認證國際軟件測試工程師認證領測軟件測試網

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>