隨筆 - 4  文章 - 16  trackbacks - 0
          <2008年7月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          常用鏈接

          留言簿(3)

          隨筆分類

          隨筆檔案

          文章分類

          新聞檔案

          好友

          最新隨筆

          搜索

          •  

          積分與排名

          • 積分 - 11213
          • 排名 - 2286

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          本節(jié)是單元測(cè)試的第三篇。我以為這是重中之重的一章。單元測(cè)試的關(guān)鍵在于代碼要可測(cè)。可測(cè)才能測(cè)。要做好單元測(cè)試,就必須在代碼的可測(cè)性方面努力,在設(shè)計(jì)、重構(gòu)方面用心。本篇主要分享我在如何寫出可測(cè)性代碼方面的理解,與大家共勉!

          單元測(cè)試(提升篇)

          ------編寫可測(cè)試性代碼

          一、可測(cè)試性設(shè)計(jì)

          1.       接口依賴

          這是最重要的一點(diǎn),因?yàn)檫@可以使得我們很容易的針對(duì)一個(gè)接口實(shí)現(xiàn)Mock對(duì)象,模擬/替換實(shí)際對(duì)象會(huì)變的很容易。達(dá)到使一個(gè)被測(cè)對(duì)象處于一個(gè)孤立環(huán)境的測(cè)試要求。


          這里,ClassA依賴于ClassB的具體實(shí)現(xiàn),TestCase根本無法獨(dú)立于ClassB對(duì)ClassA進(jìn)行獨(dú)立測(cè)試。


          因此,我們將ClassA改為依賴于接口B_Inf。這樣,可以很容易的實(shí)現(xiàn)一個(gè)Mock_B替換ClassBClassA進(jìn)行孤立測(cè)試。

          2.       依賴注入

          一個(gè)方法對(duì)外部類的依賴,應(yīng)該是可注入的。即可以通過構(gòu)造方法、get/set方法的方式在外部將依賴關(guān)系注入。事實(shí)上,這也為我們?cè)跍y(cè)試用例中替換待測(cè)類的依賴對(duì)象提供了機(jī)會(huì)。不應(yīng)該出現(xiàn)在方法內(nèi)部新建對(duì)象使用的情況。

          3.       降低耦合度

          待測(cè)類應(yīng)與最少的類耦合,即最小交互原則。特別是要減少與那些離了具體環(huán)境就不能運(yùn)行的類的耦合。可以通過門面模式等對(duì)外部調(diào)用進(jìn)行隔離。

          5AOP

          面向切面編程。給我們提供的啟示是,將真正需要測(cè)的邏輯分離出來。擺脫那些無意義且簡(jiǎn)單重復(fù)的代碼對(duì)測(cè)試的干擾。

          6.    明確的契約

          方法一定要有明確清晰的輸入/輸出。建議在方法的注釋描述中,分三段“描述”“前置條件”“后置條件”。

          二、可測(cè)試性重構(gòu)

          1.         可惡的靜態(tài)方法

          在我們的代碼中有大量的調(diào)用靜態(tài)方法的地方。用起來我們很爽,但這對(duì)測(cè)試來說卻是災(zāi)難。因?yàn)槲覀兂送ㄟ^改變代碼創(chuàng)建stub來改變這些方法的行為外,我們沒有任何途徑。更要命的是,寫這些stub的代價(jià)非常的巨大,常常令人望而卻步。

          解決方案:

          將方法內(nèi)部的這些調(diào)用提取成protected方法。在外部創(chuàng)建待測(cè)類的子類,重寫該protected方法。

          最佳實(shí)踐:


          這些靜態(tài)方法由單態(tài)類提供,單態(tài)類由工廠方法獲取,具體類使用這些單態(tài)類的接口。

          我們?cè)诜椒ㄖ型ㄟ^接口使用對(duì)外部模塊的調(diào)用。一方面,隔離了外部模塊改變對(duì)我們產(chǎn)生的沖擊,另一方面,也使我們使用Mock替換實(shí)際的外部組件,創(chuàng)建孤立測(cè)試環(huán)境成為可能。

          2.         待測(cè)類方法中,new出另一個(gè)對(duì)象并使用其方法

          兩種方案:1)將new 出對(duì)象的過程封裝成protected方法。同重構(gòu)12)將該對(duì)象提取成類屬性,即由使用關(guān)系變成關(guān)聯(lián)關(guān)系。

          3.         分離不可測(cè)/不必測(cè)代碼

          在不影響的情況下,將不可測(cè)部分分離到一些不需要測(cè)的簡(jiǎn)單方法中去。或者將可測(cè)的部分提取到一個(gè)私有方法中去。然后針對(duì)這個(gè)私有方法進(jìn)行測(cè)試。

          通常這種做法使用范圍有限,但有些時(shí)候還是值的一試。

          4.         單一職責(zé)

          職責(zé)太多,肯定不好測(cè)。針對(duì)于這一點(diǎn)“不好測(cè)的方法必然不好用”。當(dāng)方法過大,承擔(dān)責(zé)任過多時(shí),拆分是應(yīng)該的。

           

          5.         為類提供一個(gè)空構(gòu)造方法。

          我們的各個(gè)測(cè)試方法都依賴于對(duì)象處于一個(gè)特定的狀態(tài),滿足一定的前置條件。而要將對(duì)象置為我們希望的狀態(tài),我們必須首先擁有一個(gè)對(duì)象。然而,很多時(shí)候,在一個(gè)隔離的單元測(cè)試環(huán)境下,構(gòu)造函數(shù)由于各種原因不能正常初始化。

          此時(shí),可以為類提供一個(gè)的空的構(gòu)造方法。在外部構(gòu)造一個(gè)對(duì)象,而后根據(jù)前置條件將各個(gè)屬性設(shè)置成需要的Mock對(duì)象。

          -----------------------------------------------------------------------------------------------------------------------------------------------------------

          事實(shí)上,要想寫出具有可測(cè)性的代碼,最佳的辦法就是測(cè)試驅(qū)動(dòng)開發(fā)。先寫測(cè)試代碼把功能體現(xiàn)出來,再寫功能代碼讓測(cè)試通過。這樣寫出的代碼顯而易見會(huì)更具有測(cè)試性。

          posted on 2008-07-18 23:11 wukaichun 閱讀(1591) 評(píng)論(0)  編輯  收藏 所屬分類: test

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 遂川县| 漳州市| 宜宾市| 平江县| 昌黎县| 红桥区| 松桃| 辰溪县| 鄂托克旗| 宝鸡市| 营口市| 伊金霍洛旗| 象州县| 汕尾市| 明溪县| 包头市| 太原市| 西贡区| 楚雄市| 海安县| 永仁县| 闸北区| 白河县| 卓资县| 万年县| 永胜县| 彰武县| 安阳县| 青川县| 保定市| 泸溪县| 靖西县| 水城县| 和林格尔县| 揭阳市| 大同县| 浏阳市| 荃湾区| 施甸县| 阿克苏市| 连云港市|