Chapter 1 Test-Driver Development – TDD for embedded C 筆記

TDD 是一種逐步建構軟體的技巧,在寫任何程式碼之前,應該先寫 test code ,test code 通常很小且可以被自動化執行,且 test 一定會先失敗,直到你開始寫 code 來通過 test 。

Test-Driver Development (TDD) 這個方法從我大學開始聽過,後來陸續看過許多提倡使用 TDD 的文章,但他們所舉的例子都是應用於 C++, C# 或 Java 等語言,我本身工作大多都是偏向嵌入式與寫 C 語言,因此一直沒有很了解這個概念,後來無意間在天壠書局逛到這本 Test Driver Development for Embeedded C ,訝異原來 TDD 也可以應用在嵌入式 C 的領域中,因此買了這本打算研讀並應用於工作上,接下來會寫一系列的筆記來記錄我從這本書中學到的,這系列文章大多來自於這本書中。

What is TDD

TDD 是一種逐步建構軟體的技巧,在寫任何程式碼之前,應該先寫 test code ,test code 通常很小且可以被自動化執行,且 test 一定會先失敗,直到你開始寫 code 來通過 test 。

隨著你寫越多的 production code ,你也會寫越多的 test code ,test code 跟你的 production code 一樣重要。

TDD 並不是一種測試技巧,他是一種用來解決 programming problems 的方式,幫助工程師做出好的 design decisions ,test code 會在你的 production code 走歪了或是違反你原先預設的限制時馬上警告你,test code 會確保所有 production code 的預期行為正常作用,讓工程師可以專注於新的挑戰。

一般人寫程式過程是 Debug-Later Programming ,程式碼一旦寫完了,測試也被認為"做完"了,但我們都清楚,我們是人,一定會犯錯,一定會有 bug 被回報,但那都是幾天幾周甚至幾個月後的事情,bug report 回報的不即時,讓我們難以即時從中學習以避免再犯同樣的錯誤。
DLP-TDD

下圖則是 TDD 的工作流程,bug 會很快的被發現並迅速被處理。
TDDFlow-TDD

TDD 是一個不斷重複一個 microcycle 的過程,

  1. 加上一個小 test code
  2. 執行所有測試,並且看到新寫的測試不通過,甚至於無法編譯。
  3. 寫一些程式碼來讓通過測試
  4. 重構程式碼

每經歷一次這樣的 cycle 都在幫助你確認:新的程式碼跟舊有的程式碼仍然正常的工作嗎? 且每次的測試,都在幫助你建立一個知識庫,紀錄著你究竟解決什麼問題, test code 等於是你為了 requirement 所寫下的文件。

在 Refactoring: Improving the Design of Existing Code 這本書中,針對重構有以下定義:

Refactoring is the activity of changing a program's structure without changing its behavior.

重構的目的是讓程式碼更好被了解,更輕鬆的去擴展且更容易被我們自己或他人來維護,有著已經寫好的 test code ,在重構的過程中,就可以確認好程式碼的行為不會在重構過程中被破壞,尤其對於作者以外的人更改程式碼,有著 test code 可以讓其他人更無懼的去做程式碼的重構。

Benefits for embedded

前述的優點同樣適用於 non-embedded 開發者,針對 embedded 開發者還有以下幾點優勢:

  1. 降低驗證 production code 的風險,在硬體準備好之前或是硬體昂貴且稀少時,可以獨立於硬體先進行驗證
  2. 想要進行 debug ,不用花費長時間的 compile, link, and upload cycles 。
  3. TDD 幫助完成好的 software design 讓 modules 跟硬體可以彼此獨立,藉此分辨出軟硬體協作造成的 issue 還是單純的 software issue 。