為什麼你無法說服你的同事使用TDD?
這兩天讀到了一篇關於TDD的專欄文章如何說服你的同事使用TDD,正好前段時間也有思考相關的問題,有一些想法正好分享一下。
當然前述文章本身的質量還是很高的,旁徵博引,但是看過這一類文章的資深一些的工程師一定會產生一個疑問,既然利弊分析了那麼清楚,為什麼TDD沒有成為一種除了在大型開源組織和框架類項目之外(這兩者在所有的軟體項目中的比例是非常低的)被廣泛採用的開發技術?要知道從事這個行業的大部分都是「聰明人」,如果一種技術真的那麼好而沒有被廣泛的認可,那豈不是大家都是糊塗蛋?
首先,我個人經歷和觀察到的軟體開發活動是圍繞結果展開的,這個結果大部分情況下有可以量化的商業價值,也就是說無論任何類型的開發技術最終是否能流行取決於是否能以合理的成本提供這種價值,而不同的開發技術之間的替代都是基於這種性價比的評估。我無意於逐條的去批駁前述文章的觀點,因為這些觀點本身並沒有任何錯誤可言,提高代碼質量進而提高軟體質量肯定是政治正確的,而這些僅僅只是複雜的軟體開發活動的一個方面。
我把TDD是否能流行歸結於以下幾個方面的評估:
- 投入資源,實施/實踐這種方法需要消耗多少的資源?
- 軟體的類型,複雜度和成熟度,是一個應用還是一個框架?這個軟體可能有多少個特性?目前已經開發了多久?預計還需要開發多久才能完成?是否會繼續的迭代?
- 團隊成員的技術能力,團隊中經驗豐富的工程師比較多還是新手工程師比較多?
- 交付價值,採用了該技術之後,能為產品提供什麼樣的價值?
投入資源
坦白講TDD本身並不算很複雜的技術,學習曲線也沒有很陡峭,但是掌握粗泛的寫測試用例的方法並不能像你想像的那樣提高軟體質量,針對各種實際業務的case去寫能實際提高代碼質量的測試代碼是一種成本相當高的行為(甚至需要hack三方依賴的代碼),我知道有一些團隊甚至專門讓資深的工程師(一般意義上成本更高)負責寫測試用例。
軟體的類型,複雜度和成熟度
軟體本身的性質是決定TDD是否能流行的最關鍵因素,TDD不是什麼便宜的技術,而TDD代碼依附於實際產生作用的業務代碼,但本身不是並不是產品的一部分,這意味著如果這部分業務代碼如果被被刪除了,那麼TDD代碼也失去了價值,也就是投入的資源都白費了,坦白講這點非常令人沮喪,但是實際上這種過程在一個互聯網或者說外包項目的開發過程中是無法迴避的,甚至在項目的早期階段是主要過程。反之,框架級別的項目和大型基礎開源軟體在主要版本的開發過程中很少遇到類似的困擾,另外此類項目的代碼一般都廣泛存在於大部分項目中,提高代碼質量的邊際效益極高。當然這種分類本身是不精確的,只是幫助大家判別軟體本身的性質。
團隊成員的技術能力
一個資深工程師,不使用TDD幾乎一定可以比使用TDD更快的完成特性的開發和交付,從產品質量來講卻不一定有顯著的提高。因為決定產品質量的代碼是否正確絕大部分取決於對業務的正確理解和技術的正確運用,而資深工程師本身在這兩方面一般來講已經合格,使用TDD並不能直接起到什麼提高。對新手工程師來講,TDD可以幫助理解業務,但是額外編寫正確測試用例代碼的成本是否值得需要單獨評估。
交付價值
這裡我覺得可能是會產生爭議的地方了,我認為產品價值的確認並不是直接通過業務代碼,更不要說依附於業務的TDD代碼,而是最終用戶,代碼是一種載體,如果用過河比喻的話,如果你的用戶是行人,那麼獨木橋就足夠了,如果是自行車,一座石橋是個好選擇,如果是汽車,那麼鐵橋可能是必須的。當然鐵橋可以走行人和自行車,並無不妥,但是鐵橋更貴,需要更長的建造時間。在我經歷過的項目中這麼奢侈的情況屈指可數,不幸的是,似乎我所了解的其他人的開發活動也總是被資源不足的陰雲籠罩。一般來講,代碼質量對產品價值的提升,在短期內總是被高估,長期被低估,在工程師群體內被高估,工程師群體之外被低估。脫離產品談代碼這個問題上我的經驗教訓頗多,也許我會另外花時間寫篇文章談一下。
總結
我個人覺得TDD可以看作一種保險,是否需要為你的項目或者團隊購買這種保險取決於以上四個方面(也許更多?)。這些結論都是站在一個全面了解TDD技術的團隊負責人的立場上做出的,屁股決定腦袋,對於團隊中的其他人來講會存在不同的結論。另外這種評估的方法也可以適用到一般性的軟體開發方法/思想/指導原則上。
後記
坦白講我並不認為TDD那麼差勁以至於無法流行,TDD本身就源於實際的軟體開發活動的經驗積累,問題在於推廣TDD技術的主要「佈道師」或者說我所知道的唯一強制使用TDD的組織成員,這些人通過一些恐嚇性的語言,類似於「不用TDD就無法寫出高質量的代碼」,翻來覆去的百度百科詞條式的內容,「使用TDD能給你帶來12345等好處」,自我催眠式的拙劣推銷員一樣的話術,「如果不是用了TDD,xx項目簡直無法開發出來」,怎麼說呢,充滿了原教旨主義者氣息讓我或者說一部分人產生天然的抗拒。軟體開發這個行業很年輕,還在快速發展中,技術和理念本身都是基於積累的經驗不斷的改進和變化的,對個人來講不能因噎廢食,除了要根據自己自身的情況去客觀評估得出結論外,我個人也提供一些額外的建議,TDD提供了豐厚的代碼資產,思考如何利用這些資產來提高開發效率是一個很有意思的topic,另外思考利用TDD技術結合devops加速deploy也是一個可以切入的點,最後我甚至覺得如果用AI來寫代碼的話,似乎TDD也大有可為?
推薦閱讀:
※最近做的一些事情
※好書連珠彈之一 - 演算法、jQuery及PHP
※一個問題的解決過程
※「Triangle Minimal Path」──來做題吧!
※如何看待簡歷中的「精通」?