淺談測試驅動開發(fā)TDD之爭
前言
在歷史上有很多精彩絕倫的神仙打架,比如數(shù)學界的牛頓和萊布尼茨關于微積分的曠世之爭;比如量子物理中的愛因斯坦和波爾的紫禁之巔;比如足球里的梅西和C羅的旗鼓相當難分高下;又比如滴滴和快滴之間觸目驚心的燒錢大戰(zhàn)……而在軟件行業(yè)中,也同樣有神仙打架的名場面,那就不得不提的是2014年的那場——測試驅動開發(fā)(TDD)之爭。
比賽的紅方是David Heinemeier Hansson,藍方是Kent Beck。David Heinemeier Hansson 由于名字較長簡寫成DHH,Ruby on Rails 正是出自于DHH之手。而這場打架還加入了“裁判”員——Martin Fowler,在比賽中Martin Fowler記錄了紅藍雙方的每一次組合拳、上勾拳、側踹、抱摔……總結如下:
紅方DHH觀點
1.許多推動TDD的開發(fā)人員會讓你覺得:如果你不使用TDD的話,你的代碼就是骯臟的。
2.由單元測試開始驅動你的設計并不是一個好的主意。
3.TDD的概念“測試必須夠快”是目光短淺的。
4.對TDD的依賴會導致徹底忘記系統(tǒng)測試。
5.關注并且只關注單元模塊并不能有助于創(chuàng)建一套完美的系統(tǒng)。
6.100%的覆蓋率是愚蠢的。
7.程序員希望軟件是一門科學,可是它并不是。它更像是創(chuàng)造性的寫作活動。
8.優(yōu)秀的軟件并不像工程學那樣,它更像寫作。清楚簡潔的寫作要優(yōu)于復雜晦澀的寫作。
9.清晰是有好處的,好到應該將清晰性作為第一目標,而非測試覆蓋度或者測試速度。
10.成為一名優(yōu)秀的開發(fā)人員就像成為一名優(yōu)秀的作家一樣困難。
11.就像寫作一樣,成為優(yōu)秀的程序員的辦法就是以清晰為目標從而大量編寫軟件、大量閱讀軟件。
藍方Kent Beck觀點
DHH已將TDD委托給歷史垃圾堆。我很難過,不是因為我就把它從歷史的垃圾堆中拯救出來,而是因為現(xiàn)在我需要雇傭新技術來幫助我解決編程過程中的許多問題:
1.過度工程化。我傾向于“投入”我“知道”我“將需要”的功能。使一個紅色的測試變?yōu)榫G色(以及未來的測試列表)有助于我實現(xiàn)足夠的功能。我需要找到一個新的方法來保持專注。
2.API反饋。我需要找到一種新的方法來獲得關于我的API決策的快速反饋。
3.邏輯錯誤。我需要找到一種新的方法來抓住那些我很容易犯的討厭的測試錯誤。
4.文檔。我需要找到一種新的方式來傳達我對api的期望,并記錄我在開發(fā)過程中的想法。
5.感到不知所措。我真的會懷念如何使用TDD,即使我無法想象一個實現(xiàn),我?guī)缀蹩偰芟氤鋈绾尉帉憸y試。我需要找到一個新的方法,以便下一步上山。
6.將接口與實現(xiàn)思想分離。我傾向于用實現(xiàn)推測來污染API設計決策。我需要找到一種新的方法來分離這兩個層次的思維,同時在它們之間提供快速的反饋。
7.協(xié)議。我需要找到一個新的方法,精確地與一個編程伙伴關于我正在解決的問題。
8.焦慮。也許我最懷念的是TDD給我的瞬間“一切都好嗎?”按鈕。
9.我相信我會找到其他方法來解決這些問題。及時。疼痛會減輕的。再見TDD,老朋友。
神仙打架不虧是神仙打架,從那以后業(yè)界關于測試驅動開發(fā)的觀念也分成了兩派。一派主要來源自像國內的一些互聯(lián)網(wǎng)等項目中聲音——需求的迭代和更新之快,要求公司或團隊能快速交付有價值的產(chǎn)品,而TDD對于很多開發(fā)人員來說無疑是帶來了繁重的工作壓力和交付壓力。甚至有人開玩笑話說:“ Deadline Driven Development 才是第一生產(chǎn)力 ”。
當然也有人力挺TDD,“TDD并沒有死。很明顯,既然它有這么這么多的支持者,它怎么可能會死呢? 這就像在問,設計模式死了嗎?或者功能性自動化死了嗎?不,它并沒有死。而且它在將來任何時候都不會死亡。它將來可能會變成其他一些新的事物、甚至是一些更好的事物,但是它永遠不會死亡。所以讓我們跳過這一部分吧。”
關于測試驅動開發(fā)說了這么久,那么測試驅動開發(fā)到底是個啥呢?
測試驅動開發(fā)(TDD)是什么
測試驅動開發(fā),英文全稱Test-Driven Development,簡稱TDD,是一種不同于傳統(tǒng)軟件開發(fā)流程的新型的開發(fā)方法。 它要求在編寫某個功能的代碼之前先編寫測試代碼,然后只編寫使測試通過的功能代碼,通過測試來推動整個開發(fā)的進行。 這有助于編寫簡潔可用和高質量的代碼,并加速開發(fā)過程。
Kent Beck:“測試驅動開發(fā)不是一種測試技術。它是一種分析技術、設計技術,更是一種組織所有開發(fā)活動的技術”。
分析技術: 體現(xiàn)在對問題域的分析,當問題還沒有被分解成一個個可操作的任務時,分析技術就派上用場,例如需求分析、任務拆分和任務規(guī)劃等,《實例化需求》這本書可以給予一定的幫助作用。
設計技術: 測試驅動代碼的設計和功能的實現(xiàn),然后驅動代碼的再設計和重構,在持續(xù)細微的反饋中改善代碼。
組織所有開發(fā)活動的技術: TDD 很好地組織了測試、開發(fā)和重構活動,但又不僅限于此,比如實施 TDD 的前置活動包括需求分析、任務拆分和規(guī)劃活動,這使得 TDD 具有非常好的擴展性。
測試驅動開發(fā)(TDD)的目標
Kent Beck 在他的著作《Test-Driven Development》(見參考附錄)一書中提到:“代碼簡潔可用這句言簡意賅的話,正是 TDD 所追求的目標”。
對于如何保證“代碼簡潔可用”可以使用分而治之的方法,先達到“可用”目標,再追求“簡潔”目標。
可用: 保證代碼通過自動化測試。
代碼簡潔: 在不同階段人們對簡潔的理解程度也不一樣,不過遵循的原則差不多,例如 OOD 的 SOLID 原則(詳見參考附錄),Kent Beck 的 Simple Design 原則(詳見參考附錄)等。
雖然有很多因素妨礙我們得到整潔的代碼,甚至可用的代碼,無需征求太多意見,只需要采用 TDD 的開發(fā)方式來驅動出簡潔可用的代碼。
測試驅動開發(fā)(TDD)的規(guī)則
在TDD 的過程中,需要遵循的三項原則:
1.在編寫好失敗的單元測試之前,不要寫任何產(chǎn)品代碼。
2.只要有一個單元測試失敗了,就不要再寫測試代碼。無法通過編譯也是一種失敗。
3.產(chǎn)品代碼恰好能夠讓當前失敗的單元測試成功通過即可,不要多寫。
測試驅動開發(fā)(TDD)的流程
測試驅動開發(fā)是一個過程,依賴于不斷重復極短的開發(fā)周期,這個周期也稱為“紅燈-綠燈-重構”,如上圖。簡單的來說,基于TDD的三項原則,TDD的這種步驟(周期)如下:
1.添加一個小的測試
2.運行測試并查看失敗
3.對測試進行微小的改動通過測試
4.運行所有測試并看到其通過
5.通過重構去掉重復部分
需要注意的是,不同階段有不同的目的,他們需要不同的解決方案,前二個階段需要很快地完成,以便知道新添加功能的狀態(tài)。為了達成這個目的,可以通過任何手段,因為僅在這時才這樣做,也是為了能快速完成好的設計。
測試驅動開發(fā)(TDD)的好處
TDD主要的好處主要包括了,確定性、重構代碼、單元測試即文檔。
確定性。TDD提升了單元測試的覆蓋率,在每輪迭代產(chǎn)品都會新增代碼,如果有一套覆蓋率很高( 90% 或更高)的單元測試,那么只需執(zhí)跑一遍測試用例,那么能成功交付的把握就會比較大。反之,如果覆蓋率越低,越需要更多的人力去進行手動驗證。 在 kent Beck的《測試驅動開發(fā)》舉的例子中,正因有了TDD才有勇氣和老板說我們可以做!這就是TDD最強大的地方,它讓你擁有一套值得信賴的測試,打消你對修改代碼的恐懼。
重構代碼。Martin Flower在他的《重構》中也指出,完善的單元測試是他進行重構的基石,從TDD的流程可以看到,重構是TDD的一部分,運用TDD的同時也推動了代碼的重構。
單元測試即文檔。在軟件行業(yè)里,人員的變動的很頻繁的,如果要盡快熟悉某個模塊的業(yè)務邏輯??次臋n?程序員寫的文章一般都不太容易看,而且文檔經(jīng)常會和代碼不同步,代碼修改了文檔沒跟著改的事情經(jīng)常發(fā)生。看源碼?看完也不一定知道為什么。如果這時候有一套非常完整的單元測試,那可能就是所有接手別人代碼的程序員的福音。首先,代碼不會撒謊,其次,測試用例明確告訴了你這個函數(shù)是做什么的,什么輸入對應的都有什么預期輸出。單元測試就是最好的底層文檔,哪個專業(yè)人士不想提供這樣一份文檔呢?
此外,TDD還能夠促成良好的代碼設計。由于你先寫測試代碼,你會盡可能的讓代碼調用起來更加簡單方便,這也就促使你去考慮如何更好的設計代碼。以避免會出現(xiàn)一個函數(shù)里實現(xiàn)的功能過多,或者和其他代碼過于耦合而無法測試的情況。
當然測試驅動開發(fā)除了好處以外,還有神仙打架中紅方代表DHH所提出的一些問題??偨Y來看,關于TDD的爭議可以大致從這幾個方面來看,軟件開發(fā)應該由什么來驅動,測試的速度和覆蓋程度,以及設計思想層面等幾方面。從 辯證統(tǒng)一的角度來看,事物有兩個方面, TDD不一定能適用于所有的場景,同樣TDD的局限性在某些場景下也不見得是對的,如果想要能更好的適用于自身,不僅要拿捏好度的問題還要以敏捷的思想來應對問題,比如不應該盲目的制定100%或0%的測試覆蓋率,也不應該固化開發(fā)步驟而不顧實際情況。
所以,在最后的神仙打架中,Kent Beck也表達了David的論述可能會讓TDD浴火重生、鳳凰涅槃的觀點,希望可以找到更加好的方法。但無論如何, 在我們實際工作中,不應該因為某些 觀點成為我們接受或者拒絕它的理由。正所謂大道甚夷,而民好徑,作為敏捷開發(fā)中的一項優(yōu)秀實踐來看,TDD只有在真正使用過后才能評價是否已死的問題。那么你在踐行敏捷開發(fā)的時候,是否使用過TDD這種實踐呢,又或是踐行過其他一些敏捷開發(fā)的實踐呢,有沒有評測過你所在的項目中的敏捷開發(fā)的成熟度是如何的呢?
沒有那就對了!華為云的DevCloud專業(yè)服務正是為此而生!
針對不同的崗位提供了評估的能力,讓開發(fā)者可以對號入座,并基于你所在的崗位、技術得到客觀、全面、系統(tǒng)的測評以及名師般的學習引導??靵碓L問專業(yè)服務平臺,通過個人能力評估,看看自己是什么水平吧!
以上就是淺談測試驅動開發(fā)TDD之爭的詳細內容,更多關于測試驅動開發(fā)TDD之爭的資料請關注腳本之家其它相關文章!
- Android開發(fā)筆記之:對實踐TDD的一些建議說明
- QUnit jQuery的TDD框架
- SpringBoot內置tomcat調優(yōu)測試優(yōu)化
- SpringBoot+redis配置及測試的方法
- SpringBoot對Controller進行單元測試的實現(xiàn)代碼 附亂碼解決方案
- 詳解SpringBoot項目的創(chuàng)建與單元測試
- 解決SpringBoot 測試類無法自動注入@Autowired的問題
- Springboot Mybatis-Plus數(shù)據(jù)庫單元測試實戰(zhàn)(三種方式)
- Springboot集成JUnit5優(yōu)雅進行單元測試的示例
- 使用@SpringBootTest注解進行單元測試
- SpringBoot生產(chǎn)環(huán)境和測試環(huán)境配置分離的教程詳解
- Spring Boot web項目的TDD流程
相關文章
PyCharm2022激活碼破解補丁一鍵安裝免費分享(2022年持續(xù)更新)
PyCharm2022最新激活碼分享(持續(xù)更新),PyCharm激活補丁一鍵安裝簡單方便,無需手動修改文件,MAC,linux,Windows系統(tǒng)都可使用2022-07-07