談“測試驅動的開發”
原文連結:http://blog.sina.com.cn/s/blog_5d90e82f0101kfnd.html
現在的很多公司,包括 Google 和我現在的公司 Coverity,都喜歡一種“測試驅動的開發”(test-driven development)。它的原理是,在寫程式的時候同時寫上自動化的“單元測試”(unit test)。在程式碼修改之後,這些測試可以批量的被執行,這樣就可以避免不應該出現的錯誤。
這不是一個壞主意。我在 Kent 的編譯器課程上也使用了很多測試。它們在編譯器的開發中是不可缺少的。編譯器是一種極其精密的程式,微小的改動都可能帶來重大的錯誤。所以編譯器的專案一般都含有大量的測試。
但如果使用不當,測試卻會大幅度的降低開發效率。當我給 Google 開發 Python 靜態分析的時候,我幾乎沒有使用任何測試。雖然組裡的成員催我寫測試,但是我卻知道那隻會降低我的開發效率。因為這個程式在幾個星期的過程中,被我推翻重來了好幾次。要是我一開頭就寫上測試,這些測試就會礙手礙腳,阻礙我大幅度的修改程式碼。
最後的結果是,我在 12 個星期之內,寫出了 Google 一個小組的人需要幾年才做得出來的東西。現在這個東西里面的技術,仍然處於世界領先地位。就連 Coverity 這種專門做靜態分析軟體的公司,程式碼質量也無法與之相比。按照他們的開發方式,要想在 12 個星期之內做出這個東西,是完全不可能的事情。
測試的另一個副作用是,它讓很多人對測試有一種盲目的依賴心理。改了程式之後,把測試跑一遍沒出錯,就以為自己的程式碼是正確的。可是測試其實並不能保證程式碼的正確,即使完全“覆蓋”了也是一樣。覆蓋只是說你的程式碼被測試碰到過了,可是它在什麼條件下碰到的卻沒法判斷。如果實際的條件跟測試時的條件不同,那麼實際執行中仍然會出問題。唯一能可靠的確保程式碼正確的方法是使用嚴密的邏輯推理,證明它的正確。
很多人寫程式只是憑現象來判斷,而不能精密的分析程式的邏輯,所以他們修改程式經常“治標不治本”。如果程式出問題了,他們的辦法是看看哪裡錯了,也不怎麼理解,就改一下讓它不再出錯,最多再把所有測試跑一遍。或者再加上一些新的測試,用以保證這個地方下次不再出問題。
這種做法的結果是,程式裡出現大量的“特殊情況”和“補丁”。把一個“蟲子”按下去,另一個蟲子又冒出來。忙活來忙活去,最後仍然不能讓程式滿足“所有情況”。其實能夠“覆蓋所有情況”的程式,往往比能夠“覆蓋特殊情況”的程式簡單很多。這是一個很奇怪的事情:能做的事越多,程式碼量卻越少。也許這就叫做程式的“美”。
美的程式不可能從修修補補中來。它必須完美的符合事物的本質,否則就會出現上面的情況,有許許多多無法修補的特例。程式設計師跟畫家其實差不多,畫家如果一天到頭蹲在家裡,肯定什麼好東西也畫不出來。程式設計師也一樣,蹲在家裡面對電腦,其實很難寫出什麼好的程式碼。你必須出去觀察事物,尋找“靈感”,而不只是修改程式碼。在修改程式碼的時候,你必須用“心靈之眼”看見程式碼背後的事物。這也是為什麼很多高明的程式設計師不怎麼用偵錯程式(debugger)的原因。他們只是用眼睛看著程式碼,然後閉上眼,腦海裡浮現出其中資訊的流動,所以他們經常一動手就能改到正確的地方。
相關文章
- Laravel 測試驅動開發 -- 正向單元測試Laravel
- TDD(測試驅動開發)死了嗎?
- 什麼是測試驅動開發
- 變異測試是測試驅動開發(TDD)的演變
- 測試驅動開發(TDD)例項演示
- 淺談自動化測試框架開發框架
- 測試驅動開發(TDD)實戰心得 - DeniMoka
- 測試驅動開發在專案中的實踐
- 測試驅動開發(TDD)總結——原理篇
- 驅動開發目標測試機器設定
- 使用Spring Boot REST API進行測試驅動開發Spring BootRESTAPI
- 測試驅動開發(TDD)—— 資料庫查詢篇資料庫
- Fitness function-driven development(測試驅動開發) 翻譯Functiondev
- 測試開發之單元測試-禪道結合ZTF驅動單元測試執行
- Linux驅動開發: Ubuntu(PC機)系統上編譯驅動並載入測試LinuxUbuntu編譯
- 簡單的11步在Laravel中實現測試驅動開發Laravel
- 簡單的 11 步在 Laravel 中實現測試驅動開發Laravel
- 使用 TDD 測試驅動開發來構建 Laravel REST APILaravelRESTAPI
- 測試驅動開發TDD | IDCF FDCC認證學員作品
- golang 表格驅動測試Golang
- 有自驅力的測試開發實習生
- Python 實現行為驅動開發 (BDD) 自動化測試詳解Python
- Swift 進階開發指南:如何使用 Quick、Nimble 執行測試驅動開發(TDD)SwiftUI
- Android 談談自動化測試Android
- golang 表格驅動測試案例Golang
- 驅動開發:配置Visual Studio驅動開發環境開發環境
- Go 語言:透過TDD測試驅動開發學習 Mocking (模擬)的思想GoMock
- 基於事件驅動的測試框架ETS事件框架
- TestComplete使用關鍵字測試的資料驅動測試(三)
- 關鍵字WebElement 驅動測試Web
- 淺談自動化測試
- iOS自動化測試驅動工具探索iOS
- 採用測試驅動開發理念(Test Driven Development)進行 SAP UI5 應用的功能開發(一)devUI
- 採用測試驅動開發理念(Test Driven Development)進行 SAP UI5 應用的功能開發(二)devUI
- RQM — 需求驅動的測試管理工具
- 開發商談手遊測試發行過程的關鍵因素
- DDT資料驅動效能測試(一)
- 《C++程式設計實踐與技巧:測試驅動開發》 環境搭建遇到的坑C++程式設計