雜談 - 關於設計:TDD 邪教論


雜談系列其實就是一時性起隨手亂寫的心得文,
主要談談最近聽看到的一些議題
也跟開發有關,有興趣隨意看

起源

日前有篇國外文章條列了一些關於軟體開發的看法
其中就有提到 TDD 是一種邪教

本來我覺得也就那樣吧
每種手段的好與壞每個人基於不同情境、經驗其實就會有不同想法

TDD 邪教論其實也不是一天兩天的事......

結果想不到還真的能引發一些討論,
然後台灣的一些網路社群也開始跟著討論測試要怎麼搞
當然也確實不激烈,不如當初 TDD 剛出來的時候很常會戰到血流成河的景象

那麼我也來談談我的看法好了
其實所有的設計或開發手段
你都應該理解其背景、解決問題的思路
你才能有比較客觀的判斷

TDD 基本原理和思路

TDD 的本質是希望測試能領先於實際開發,
然後藉由測試代碼完成系統的 scaffolding
用測試去對系統塑形之後再把實際程式寫出來

而經歷一段開發週期之後,可能系統會需要進行重構
這些測試也能夠當作重構途中的一些檢查點來保護你不會從鷹架上摔死

這些屬於 TDD 原始的目的和基本性質

TDD 的矛盾所在

關於重構這件事

其實很多的系統開發途中遭遇的重構本質上是一種對問題理解的改變。

這並不是一種「強化」而是一種根據實作面上的需求改變的設計變更所導致。

對於這種情況,先前的設計本質上其實是一種 false design
而基於這些 false design 所設計的 test case 當然也只會是一堆 false design

這些 test case 不僅不會起到鷹架的作用,反而會變成陷阱和絆腳石

你可能會需要花大把時間去跟這些 test case 做"妥協"
為什麼要妥協呢?設計改了 test case 一併改就好了不是嗎?

事實上,你可以這麼做

但相對的,你傷害了 test case 的權威性

如果修改 test case 的事情可以輕易的一而再,再而三的發生
那麼日後對 bug 的理解可能就會優先懷疑 test case 是 false design,從而喪失我們設計 test case 的價值

所以某種意義上 TDD 其實是一個存在矛盾的方法論。

test case 之所以可以做為系統穩定性的錨點,其原因就在於它是基於一個成熟穩定的設計和需求理解設計出來的代碼
而走在開發流程最前緣的階段,不可能是成熟穩定且理解完備的

來回覆一些比較有趣的問題

這些問題跟文章核心不見得有關,但是就很有趣

大量但小比例的 test case 失敗需不需要全部 review

其實這是不可能的,你沒有那個時間可以 review 所有的 failed case

但是我有發現一些比較有見識的回覆,大意是說
「其實大量 fail 很常見,但是你只需要少量的修改就能修復所有的 fail, 所以不需要全部 reivew」

這個概念源自於 failed is clustered, 簡單來說就是這些 failed 都是同一隻 bug 導致的

學理上和實務上都正確

但是用在這裡其實就倒果為因

這件事正確的前提在你的 failed 是 true negative,也就是他是真的被你弄壞的。

而如果你的 test case 落在 false negative 的區域,他就不適用這個道理
因為這些 failed case 最後會被標上 not a bug,也就沒有所謂同一 bug 導致 failed cluster 的現象。

需求變,測試變,天經地義

但是你會發現有的測試需要改有的測試不用,這是為什麼呢?

喔,因為有的測試跟需求變更的功能有關,有的無關。

那麼,你怎麼知道被你修改的 test case 是本來就應該有關的呢?

再更清楚一點說,test case 和變更之間的 dependency 是不是值得考驗的一件事?

退一步說,一次需求變更設計和實作會一次就到位嗎?

#software engineering #software design #tdd #test







你可能感興趣的文章

docker 是什麼:快速部署應用程式的實用工具

docker 是什麼:快速部署應用程式的實用工具

Angular 9 + Firebase (1) : AngularFire 快速安裝

Angular 9 + Firebase (1) : AngularFire 快速安裝

函式 Function

函式 Function






留言討論