前言
這次筆者希望可以用 30 篇文章,來讓讀者了解 TDD 完整流程中,每一個環節的重要性,以及它們彼此之間如何環環相扣,發揮綜效,以降低每個環節與每個角色之間轉換的 effort 。
這一系列 30 篇文章,筆者有精心規劃過順序,所以強烈建議讀者,可以的話請按照順序來閱讀。文中也有許多交互參照的 reference ,按照順序閱讀與練習,會更能將自己沉浸在 TDD 過程的節奏中,而且每一篇文章中,所需要花費的練習時間相當簡短,每一個概念精簡而重要,就跟物件設計的封裝原則一樣,「最少但是又缺一不可」。
一步一步去了解文中所提倡的精神,一步一步跟著文中範例去練習,當碰到了瓶頸,我想恭喜您,就跟 TDD 中碰到紅燈一樣讓人開心,跨過去了,你就得到它了!按照筆者安排的難易度,每一篇文章只要有寫過程式碼的朋友,應該就能跟的上這樣的步調才是。
接下來是 30 篇文章的分類,希望對大家在閱讀或 survey 整個 TDD ,可以有所幫助。
TDD 概念大綱
測試相關
- [30天快速上手TDD][Day 2]Unit Testing 簡介
- [30天快速上手TDD][Day 3]動手寫 Unit Test
- [30天快速上手TDD][Day 4]是否需針對非 public method 進行測試?
- [30天快速上手TDD][Day 5]如何隔離相依性 - 基本的可測試性
- [30天快速上手TDD][Day 6]隔絕相依性的方式與特性
- [30天快速上手TDD][Day 7]Unit Test - Stub, Mock, Fake 簡介
- [30天快速上手TDD][Day 8]Integration Testing & Web UI Testing
重構九式
- [30天快速上手TDD][Day 9]Refactoring legacy code 簡介
- [30天快速上手TDD][Day 10]Refactoring 起手式 - 建立測試
- [30天快速上手TDD][Day 11]Refactoring - 讓程式碼說話
- [30天快速上手TDD][Day 12]Refactoring - 職責分離
- [30天快速上手TDD][Day 13]Refactoring - 告訴我,你要什麼
- [30天快速上手TDD][Day 14]Refactoring - 驗貨
- [30天快速上手TDD][Day 15]Refactoring - 食神歸位
- [30天快速上手TDD][Day 16]Refactoring - 介面導向
- [30天快速上手TDD][Day 17]Refactoring - Strategy Pattern
- [30天快速上手TDD][Day 18]Refactoring - Factory Pattern
- [30天快速上手TDD][Day 19]Refactoring - The End is the Beginning
ATDD
- [30天快速上手TDD][Day 20]ATDD - User Requirement
- [30天快速上手TDD][Day 21]ATDD - Acceptance Testing
- [30天快速上手TDD][Day 22]ATDD - ATDD的循環
BDD & TDD
- [30天快速上手TDD][Day 23]BDD – Introduction
- [30天快速上手TDD][Day 24]BDD - SpecFlow Introduction
- [30天快速上手TDD][Day 25]BDD - TDD from BDD
整套的TDD流程
TDD 實戰演練
- [30天快速上手TDD][Day 27]TDD 實戰練習 part 1–ATDD 第一個紅燈
- [30天快速上手TDD][Day 28]TDD 實戰練習 part 2–第一個綠燈
- [30天快速上手TDD][Day 29]TDD 實戰練習 part 3–單元測試綠燈
- [30天快速上手TDD][Day 30]TDD 實戰練習 END
實戰範例的 Sample code 下載位置
Reference
書籍:
- The Art of Unit Testing: With Examples in .Net
簡體中文:.NET單元測試的藝術 - Test Driven: TDD and Acceptance TDD for Java Developers
簡體中文:测试驱动开发的艺术 - Refactoring: Improving the Design of Existing Code
繁體中文:重構:改善既有程式的設計 (二版)
簡體中文:重构:改善既有代码的设计 - Refactoring to Patterns
繁體中文:重構-向範式前進
簡體中文:重構與模式 - Agile Principles, Patterns, and Practices in C#
簡體中文:敏捷软件开发:原则、模式与实践 - Growing Object-Oriented Software, Guided by Tests
簡體中文:測試驅動的面向對象軟體開發 - Emergent Design: The Evolutionary Nature of Professional Software Development
簡體中文:浮现式设计:专业软件开发的演进本质 - Brownfield Application Development in .Net
繁體中文:軟體構築美學:當專案團隊遇上失控程式,最真實的解決方案 - Succeeding with Agile: Software Development Using Scrum
簡體中文:Scrum敏捷软件开发 - Scrum and XP from the Trenches (Enterprise Software Development)
簡體中文:硝烟中的Scrum和XP:我们如何实施Scrum
大家可能會有個疑問,怎麼書裡面沒列到 TDD 的經典本:Test Driven Development: By Example ( by Kent Beck ),嗯,原因很簡單,我沒有看完,只有看了最前面的幾章...當時拿來當切入 TDD 的第一本入門書,讓我有點卡彈,可能是我英文不夠好、可能沒那麼剛好敲到我欠缺的部份,但可以確定的是, Kent Beck 在 TDD 的書,肯定值得閱讀。
結論
最後想提醒一下讀朋友們, user story/ATDD/BDD/TDD/Refactoring ,這些概念都不會因為語言、平台、工具而有所不同。
在各種不同的環境下,只要掌握這些概念,有過幾次完整套用的實務經驗,要體會其中各個環節自然不會是太大的問題。當然,如果是要導入到團隊中的話,那麼眉角會更多,先讓自己去了解、練習,並試著應用到實務上,您鐵定會碰到不少實務上的問題,這些問題,才是真正的「價值」。
把這些東西內化之後,自然您就不會感受到什麼成本、時程的問題,因為在開發時,這一切就跟呼吸一般自然。掌握你的節奏、團隊的節奏,這樣子開發過程,會是一個很美妙的世界的。
關連文章
[BDD][TDD]BDD in .NET–TDD 在實務上最後一塊拼圖 (投影片分享)
[Tool]FxCop 透過 Command Line 使用自訂 RuleSet 分析
回應
# re: [30天快速上手TDD]目錄與附錄 by Hsuan
HI, 91大大
關於DAL(資料存取層)的程式, 要如何做單元測試呢?
DAL的目的就是和資料庫之間存取, 所以一定會與外界(指的是DB)有關聯, 這樣不是就違返了"單元測試"的精神了..
麻煩您抽空解惑一下, 感謝
2013/12/25 下午 05:14 | 回覆
# re: [30天快速上手TDD]目錄與附錄 by 91
to Hsuan :
我是傾向DAL可以不作單元測試,但這需要你們開發的規範來輔助。
如果DAL沒有商業邏輯,那我想重視的應該是最後跟資料面存取的結果,沒有商業邏輯,我覺得不太需要單元測試,因為重視最後資料存取的結果,所以有需要的話,我會加入整合測試。這個整合測試的入口,仍是針對DAL的物件,而非使用者的角度。只是這個整合測試會直接與測試DB耦合並進行驗證。
一般開發團隊如果對測試跟敏捷還沒有相當貫徹的話,那我不建議太著重在DAL的整合測試,而是先讓BLL的單元測試跟程式碼品質可以貫徹一些,這樣投資報酬比才會高。其他的部分,只要當發生問題時,你可以快速的建立一個對應的測試案例,預期是綠燈,卻真的出現紅燈,修復程式後,重新執行可以變成綠燈即可。
因此,BLL若有完整的單元測試,當發生問題時,你可以快速釐清是否為BLL的問題,若不是,則問題要嘛就是PL,要嘛就是DAL,要嘛就是整合上的問題,因此可以快速地釐清問題的原因,這樣就很夠了。
除了BLL要有完整的單元測試以外,我也建議要有一定的 acceptance testing,透過使用者的 scenario 來達到更完整的「整合測試」,這些 scenario 勢必一定會包含DAL的部分,因此 acceptance testing 作最上層的黑箱測試,當發生不如預期的結果,則在BLL加入單元測試,釐清問題的根本原因在哪。
這是我目前覺得投資報酬比比較高的自動測試導入方式。
最後提醒一下,任何一個 defect 的測試案例都是珍貴且重要的,因為累積這些 defect 的測試案例,就能讓產品的品質更加穩固。
2013/12/25 下午 06:22 | 回覆
# re: [30天快速上手TDD]目錄與附錄 by Hsuan
to 91 :
感謝91大的精闢解說~
2013/12/26 上午 10:03 | 回覆