qileilove

          blog已經轉移至github,大家請訪問 http://qaseven.github.io/

          解讀TDD的五大誤區

           摘要:所謂TDD簡單地說就是以下兩個步驟:確保所有的需求都能被照顧到;在代碼不斷增加和重構的過程中,可以檢查所有的功能是否正確。本文我們一起來看下關于TDD的五大誤區。

            TDD(全稱Test Driven Development)測試驅動開發,是一種軟件開發的流程,其由敏捷的“極限編程”引入。其開發過程是從功能需求的測試用例開始,先添加一個測試用例,然后運行所有的測試用例看看有沒有問題,再實現測試用例所要測試的功能,然后再運行測試用例,查看是否有case失敗,然后重構代碼,再重復以上步驟。

            其理念主要是確保兩件事:

            ● 確保所有的需求都能被照顧到。

            ● 在代碼不斷增加和重構的過程中,可以檢查所有的功能是否正確。

            原文作者Adam Bar在拜讀了Bradley Braithwaite的文章后引發了一些思考,對此,他補充了對TDD的一些看法,列舉出TDD的五大誤區。以下是文章譯文:

            1、即使沒有單元測試,也比有單元測試做的差要好。 (It's better to have no unit tests than to have unit tests done badly )

            2、利用代碼測試能夠產生許多高效的代碼且代碼看起來更加可靠、實用。

            一、不要使用Mocking Framework VS 太多測試設置

            也許有人會說,這兩點很矛盾,因為使用Mocking Framework會導致產生過多的測試設置。這就需要我們保持一個良好的平衡問題。

            測試代碼勢必會產生一些依賴關系,倘若不使用Mocking framework,那么我們將無法進行單元測試。這一點是肯定的。

            這里例舉有關代碼測試和數據庫的例子——我們通常稱之為集成測試、half-arsed測試,這也是測試查詢本身唯一可靠的方法。

            但是,在大多數情況下,我們使用stubs,避免使用mocks——兩者之前的區別非常重要。Mocks作為一種行為測試工具常被用來執行檢查過度使用的自定義測試,同一個人在同一時間編寫代碼,就如同檢查我們剛剛故意創建的設計一樣。 TDD導致大量的Mock和Stub。Test Case并不一定是那么容易的,如果你的Test Case中的Mock可能是錯的,你需要重寫他們。也許你會說,就算是不用TDD,在正常的開發過程中,我們的確需要使用Mock和Stub。沒錯!的確是這樣的,不過,記住,我們是在實現代碼后來決定什么地方放一個Mock或Stub,而不是在代碼實現前干這個事的。所以,TDD中,Test Case是開發中最重要的環節,Test Case的質量的問題會直接導致軟件開發的正確和效率。

            我們更加關注的是真實的驗證結果(stubs將帶給你很多幫助),而不是通過耦合來實現。 沒有什么比維持一個測試套件和spaghetti-flavoured mock 裝置更糟糕的事了。

            二、主張太多元素

            在每次測試時主張有一個邏輯是很好的規則。即使它意味著調用幾個Assert,但對我來說,使用任何asserts 都是同等重要。

            三、追溯編寫測試

            大多數TDD的獲益方式,從實施前就可進行思考。比如: 寫測試需要成本,測試需要維護。

            許多開發者認為這不僅這是通往幸福的路徑,還有關于負面的情況及邊界值(boundary values )。  此外,它還強烈支持KISS和YAGNI原則,這對于長期代碼庫來說非常重要。

            我個人比較喜歡使用TDD來配合檢測錯誤報告。通過重新創建失敗條件來編寫失敗的單元測試使得更容易,這將有助于隔離故障,分析根本原因所在,這往往比在現實生活的情況下重現 bug容易得多。追溯編寫測試只適用于集成測試中查找Bug。

            四、測試過多代碼

            這是一條放之四海而皆準的普遍真理。

            在利用單元測試核心代碼中我看到許多有價值部分。創建這些代碼我更多的是根據TDD原則創建而來(尤其是沒有產生錯誤的代碼及沒有失敗的測試)。

            但是我并不把100% 的代碼覆蓋率作為最終目標,因為這樣沒有任何意義。

            我想,總會有相當多的代碼不只是適用于單元測試,即協調/組織類型的代碼(我們稱之為組成節點將其作為組成root的引用),它們需要一些依賴關系,通過調用幾種方法,把代碼從這里移植到那里,無需添加任何邏輯,而無需真正干擾數據。

            由于其沉重的mocks和stubs 的使用,這種編寫測試的代碼比代碼本身要復雜的多。Bradley的經驗法則對我來說:為每一個IF, And,Or,Case,For,While條件語句編寫一個單獨的測試,當所有分支/條件語句被覆蓋時,該代碼將會被完全覆蓋。

            五、TDD跟測試的關系

            測試是TDD的必然結果。如果團隊一直在實踐TDD,所有的代碼都會有相應的測試,所有的測試其實就是整個系統的腳手架。 TDD方式的開發是從寫測試開始的。

            使用TDD時,功能開發總是實現溝通結束條件,也就是在何種情況下,可以認為功能完成,這個結束條件是以測試體現的。

            實踐TDD時,寫代碼只有兩種目的:1、讓一個失敗的測試通過。2、在不添加新功能(也就是不需要添加新的測試)的前提下,讓代碼、結構或者測試更加清晰、整潔、易懂。

            對于需求來說,TDD更能引導開發人員做出真正符合需求的東西,不會過渡開發。對于設計來說,TDD的實踐能幫你清理思路,但不能教會你做好的設計。對于質量來說,TDD保證所有的代碼都有測試覆蓋,肯定能提高質量。

            寫在最后:

            對此,有專家建議想要用TDD請首先學會測試的基本功,另外要養成沒有測試過的功能堅決不算結束的功能的習慣,這個習慣很重要。為什么TDD狂熱者能夠report出極少數量的bug的原因之一,就是養成經常性測試的習慣。

            使用 TDD 的目的是高效的開發高品質的程序。如果發現 TDD 危及這個目標(沒有完美的開發模式,TDD也有自身的弱點和局限),那么請適當的妥協。

          posted on 2013-02-17 11:32 順其自然EVO 閱讀(190) 評論(0)  編輯  收藏 所屬分類: 測試學習專欄

          <2013年2月>
          272829303112
          3456789
          10111213141516
          17181920212223
          242526272812
          3456789

          導航

          統計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 颍上县| 克拉玛依市| 子洲县| 吉林省| 清涧县| 宜黄县| 大埔区| 江源县| 监利县| 博白县| 尼木县| 吉木乃县| 桐乡市| 江源县| 富裕县| 阿克| 平乡县| 雷山县| 皋兰县| 广汉市| 淮阳县| 修水县| 维西| 峨眉山市| 西乡县| 连城县| 南部县| 绥滨县| 永州市| 西畴县| 和龙市| 临湘市| 阿克苏市| 新乡县| 阿克陶县| 左权县| 额尔古纳市| 邵阳市| 莱州市| 宜春市| 博罗县|