[隨筆] 開發人員對 TDD 的心魔

為啥開發人員都覺得 TDD 好,卻又覺得在實務上有些彆扭,也有很多說法把它講得有些不切實際、太理想化呢?

你以為它是測試,但其實在它的本質上,同時兼具了「Specification」與「Test」兩種維度的身份。

隨筆記錄下來想法,這個「測試驅動開發」的「測試」,可能跟你想得不一樣。

為什麼 TDD 距離感這麼遠

絕大部分的團隊或開發人員,對於 TDD 覺得彆扭的原因,通常是因為他們拙於寫測試,而更糟糕的是,他們覺得「測試驅動開發」的「測試」真的只是「拿來測試用的測試程式」。

上面這樣說起來有些弔詭,待我娓娓道來。

測試不是測試?你在說什麼?

大家常提出的疑問是:「為什麼我寫 production code 之前要先寫測試?我寫 production code 都沒時間了。何況,我先寫完 production code 後,如果有時間的話,我再來寫測試,不是很好?先完成 must have, 再來完成 should have 的部分,合情合理。」

這樣講,也沒錯。如果測試驅動開發的測試,只是測試的話

如果是先有需求規格再寫 production code 呢?

大家都覺得別人的規格開得很爛,那就不如給自己開規格吧。而且這樣的規格文件可以被自動產生出來,被自動執行,還可以看到執行的結果是成功還是失敗。

如果是為了先想好自己的目的跟驗證方式,再寫 production code 呢?

就算你寫 production code的過程被中斷了,或是需要暫時停止,或是需要迭代式的交付,那你的目標隨時會告訴你,是否偏離方向了,是否已經完成需求了。

如果是先想清楚,使用者、使用端到底要怎麼用我接下來提供的功能或產品,才會比較好用?

是不是其實是先想好 do the right thing 跟 eat your own dog food 呢?

測試不只是測試

這一些都不是「測試」(CHECKING)在做的事,反而比較像是需求描述、目標捕捉、建立邊界、迭代演進,只把力氣精準地花在目標上而不浪費。我們只是「恰巧」用了模樣長得像是「測試程式」的方式來進行上面這幾件事罷了。

但是因為用了「測試程式」來進行上面這幾件事,在 production code 開發完成時,它又恰巧可以真正扮演「自動測試」的工作,例如驗證程式運作是否符合預期,驗證有沒有改 A 壞 B 的情況,再透過測試覆蓋的路徑來觀察是否多寫了不必要的程式碼,或是遺漏了描述需求的測試案例。

所以 Kent Beck 以一篇「RIP TDD」來反串說明,TDD 可以「一次滿足你哪些需求跟解決哪些問題」,你不一定要使用 TDD,只是這是目前能只花一份工,卻可以同時滿足這些要求的最有效益的開發方式。如果你有更好的方式,歡迎你公開提出來,造福世人。(有比 TDD 更適合、更好的方式,傻子才抱著 TDD 不放。)

總結

測試驅動開發的「測試」,精髓在先定好想要的目標,強迫自己先想清楚最終目標,以終為始,避免自己走偏、迷惘、花時間在不必要的功能上。測試驅動開發的測試,不只是測試,更是一種需求的描述。

對敏捷開發有興趣的朋友,可以參考我的粉絲專頁:91敏捷開發之路

對 TDD 課程有興趣的朋友,課程內容、大綱與學員心得,可以參考 skilltree 的公開課程:自動測試與 TDD 實務開發

若需要聯絡我,可以透過粉絲專頁私訊或是側欄的關於我。