我是一名喜歡追求高質量代碼和高效率工做的軟件開發工程師,所以我學習 SOLID 和 Simple Design 等原則、閱讀優秀的開源代碼、閱讀相關的書籍、學習軟件過程方法和真實項目實踐,可是在追求高質量代碼的道路上,總感受目前的知識還不能幫我塑形成一種思惟框架。在 2018 年年初機緣巧合閱讀了TDD(測試驅動開發)培訓錄這篇文章,瞬間欣喜若狂!程序員
到如今接觸 TDD 將近一年,期間由於沉不下心只閱讀了不多的資料就在項目中實踐了一段時間,獲得的效果還不錯,自覺得已經很理解 TDD 實踐和背後的思想,結果在不斷閱讀相關書籍和關於一些 TDD 的討論中不斷暴露本身的無知,發現本身就像站在「達克效應」曲線的愚昧之巔,原來大部分自認爲正確的知識都是不許確甚至是錯誤的。不過我很享受這種過程,在學習的過程當中不斷驗證本身的知識是很是有趣的,這使我變得更有自知之明的同時也在不斷突破自身的認知上限。編程
接下來我會經過圖文的方式總結這段時間來對 TDD 的實踐和思考,以便於沉澱自身對 TDD 的理解,但願對讀者有所幫助,也但願讀者能夠指點一二,集思廣益才能離真相更進一步。框架
Kent Beck:「測試驅動開發不是一種測試技術。它是一種分析技術、設計技術,更是一種組織全部開發活動的技術」。
分析技術: 體如今對問題域的分析,當問題尚未被分解成一個個可操做的任務時,分析技術就派上用場,例如需求分析、任務拆分和任務規劃等,《實例化需求》這本書能夠給予必定的幫助做用。函數
設計技術: 測試驅動代碼的設計和功能的實現,而後驅動代碼的再設計和重構,在持續細微的反饋中改善代碼。單元測試
組織全部開發活動的技術: TDD 很好地組織了測試、開發和重構活動,但又不只限於此,好比實施 TDD 的前置活動包括需求分析、任務拆分和規劃活動,這使得 TDD 具備很是好的擴展性。學習
Kent Beck 在他的著做《Test-Driven Development》一書中提到:「代碼簡潔可用這句言簡意賅的話,正是 TDD 所追求的目標」。測試
對於如何保證「代碼簡潔可用」可使用分而治之的方法,先達到「可用」目標,再追求「簡潔」目標。優化
可用: 保證代碼經過自動化測試。編碼
代碼簡潔: 在不一樣階段人們對簡潔的理解程度也不同,不過遵循的原則差很少,例如 OOD 的 SOLID 原則,Kent Beck 的 Simple Design 原則等。設計
雖然有不少因素妨礙咱們獲得整潔的代碼,甚至可用的代碼,無需徵求太多意見,只須要採用 TDD 的開發方式來驅動出簡潔可用的代碼。
在 TDD 的過程當中,須要遵循兩條簡單的規則:
第一條規則的言下之意是每次只編寫剛恰好使測試經過的代碼,而且只在測試運行失敗的時候才編寫新的代碼,由於每次增長的代碼少,即便有問題定位起來也很是快,確保咱們能夠遵循小步快跑的節奏;第二條規則就是讓小步快跑更加踏實,在自動化測試的支撐下,經過重構環節消除代碼的壞味道來避免代碼日漸腐爛,爲接下來編碼打造一個溫馨的環境。
關注點分離是這兩條規則隱含的另外一個很是重要的原則。其表達的含義指在編碼階段先達到代碼「可用」的目標,在重構階段再追求「簡潔」目標,每次只關注一件事!!!
簡單來講,不可運行/可運行/重構——這正是測試驅動開發的口號,也是 TDD 的核心。在這個閉環中,每個階段的輸出都會成爲下一階段的輸入。
假設這樣的開發方式是可能的,那我採用 TDD 真正的動機是什麼?
有一個有趣的想象,當我感受壓力越大,自身就越不想去作足夠多的測試。當知道本身作的測試不夠時,就會增長自身的壓力,由於我擔憂本身寫的代碼有 BUG,對本身編寫的代碼不夠自信,這是一種心態上的變化。此時測試是開發人員的試金石,能夠將對壓力的恐懼變爲平日的雜事,採用自動化測試,就有機會選擇恐懼的程度。
若是我作了一週的規劃,而且量化成一個個可操做的任務寫到 to-do list,而後使用測試驅動編碼,把完成的任務像這樣劃掉,那麼個人工做目標將變得很是清晰,由於我明確工期,明確待辦事項,明確難點,能夠在持續細微的反饋中有意識地作一些適當的調整,好比添加新的任務,刪除冗餘的測試;還有一點更加讓人振奮,我能夠知道我大概何時能夠完工。項目經理對軟件開發進度能夠更精確的把握。
這三條規則的目的是達到代碼的「可用」目標,只須要鍵入咱們認爲正確的代碼使測試程序儘快經過便可。
不管是測試程序覆蓋的範圍仍是重構時的中間步驟,TDD 建議是採用儘可能小的步伐(測試沒法再拆分,微小的重構),可是也沒有強制必定按照這種步伐,不一樣人的步伐能夠不一樣,能夠在實踐中不斷尋找適合本身的步伐,可是前提必須儘可能小。
除了那些不寫測試還能對本身的代碼感到很是自信的人以外,這取決於本身的經驗和對代碼的信心程度。若是某些代碼本身認爲即便不須要測試,運行和重構時也很是有信心,就能夠不須要測試,好比大部分 set get ;相反,若是去掉會讓本身感到不安,就須要考慮加入測試。
這個問題《測試驅動開發》做者 Kent Beck 也很難去證實,由於沒有專門的人真正去作過這個統計,因此他表示不否定可能存在一些更好的順序設計。
由於要儘快使測試運行起來,這樣能夠下降來自系統的反饋週期,若是可以快速持續獲得來自系統的反饋,那麼就能夠持續保持小步快跑的節奏。若是能夠短期實現一個好的設計,寫出優雅簡潔的代碼,那麼在一開始 TDD 的時候,就應該採用最好的設計,由於這樣的效率會比較高。
TDD 不是銀彈,遇到問題須要尋找核心痛點是什麼,而後再對症下藥。
與 ATDD 不一樣, UTDD 主要面向的是開發人員,因此 UTDD 在這裏主要關注的是軟件內部的質量屬性,若是說軟件的外部質量體如今「缺陷數」和「缺陷率」等指標,那軟件的內部質量屬性體如今代碼的「可測試性」、「可讀性」和「可擴展性」等,這些幾乎是每一位軟件開發工程師的追求。「單元測試」做爲 TDD 的產物之一,爲了把控軟件內部的質量屬性,一般會使用到自動化「單元測試」做爲軟件質量保證的「根基」。
在計算機編程中,單元測試(英語:Unit Testing),一般由軟件開發人員編寫,用於確保他們所寫的代碼匹配軟件需求和遵循開發目標,是針對程序模塊(軟件設計的最小單位)來進行正確性檢驗的測試工做。
每一個理想的測試案例獨立於其它案例;爲測試時隔離模塊,常用 stubs、mock 或 fake 等測試馬甲程序。
一般來講,程序員每修改一次程序就會進行最少一次單元測試,在編寫程序的先後極可能要進行屢次單元測試,以證明程序達到軟件規格書要求的工做目標。
從維基百科的描述中能夠看出單元測試擁有以下特色
這裏從我我的的角度對單元測試進行簡單的分析,但對「單元測試」的理解,或者是它所處的位置仍是不夠清晰,因此接下來我使用了「測試金字塔」模型來幫助我站在一個更高的視角理解「單元測試」。
上圖的「測試金字塔」模型按照運行速度和投入成本兩個維度對不一樣階段的測試工做進行很是直觀的可視化,能夠看到單元測試是位於「測試金字塔」的最底部,很明顯「單元測試」相對於其它不一樣階段的測試工做,擁有速度快(運行效率),成本低(維護成本)的優點,同時也是做爲上層測試工做的支撐,體現了「單元測試」的重要程度。
紙上得來終覺淺,惟有知行合一,經過理論指導實踐,在實踐中不斷總結經驗,不斷驗證本身的知識,才能不斷對 TDD 有更深刻更正確的理解。接下來將計劃出幾篇文章演示使用 TDD 如何解決一些真實的案例的總結,以便於提升本身的 TDD 技藝。