Test優先驅動開發中 常見問題與對應思路
一.什麼是測試驅動開發。
引用維基定義。
測試驅動開發 (英語:Test-driven development,縮寫為TDD)是一種軟體開發過程中的應用方法,由極限程式設計中倡導,以其倡導先寫測試程式,然後編碼實現其功能得名。測試驅動開發始於20世紀90年代。測試驅動開發的目的是取得快速反饋並使用“illustrate the main line”方法來構建程式。測試驅動開發是戴兩頂帽子思考的開發方式:先戴上實現功能的帽子,在測試的輔助下,快速實現其功能;再戴上重構的帽子,在測試的保護下,通過去除冗餘的程式碼,提高程式碼質量。測試驅動著整個開發過程:首先,驅動程式碼的設計和功能的實現;其後,驅動程式碼的再設計和重構。
二.實際開發碰見的問題
很多同學在學完了test優先開發後,往往第一次實踐是嚴格按照開發順序來的,先寫spec,再寫測試,再實現程式碼。
但是,第二次開發可能就沒這麼來了,或者沒那麼嚴格了,可能是寫完spec後,先寫程式碼,再去寫test,也可能spec也沒寫直接去實現程式碼。最後要麼寫出來的測試樣例不能充分證明程式正確性,沒有嚴格劃分等價類與多種測試策略,變成低效的“白盒測試 ”,要麼就是寫出充滿風險的不可信程式碼,導致前功盡棄,開發混亂。
那麼為什麼會出現這樣類似的困境呢?
實際上同學之所以會像上面提及的那樣改變開發順序不是沒有道理,往往是下列兩種情況。
第一類,前期工作沒做好。
很多同學對spec 的概念和模式不熟悉,對這種通過特定形式描述自己要開發內容的手段不理解。導致寫的spec並不好,起不到應有的指導作用。於是導致同學對這個要開發的程式認識很模糊。接下來根據順序他寫完spec後需要寫一個測試自己類的test,但是困於對開發物件的認識不夠清晰,這一步根本做不了。
那怎麼辦呢?只有先去實現要寫的具體程式碼,在不斷實現中思路漸漸清晰後,才能去寫test,但是為了證明自己實現的思路是沒問題的,他需要邊寫程式碼邊debug,確保最終能做出來。 那麼當他這麼一路做下來後,能看見的bug往往已經解決了,看不見的bug也不知道會藏在哪裡,無法通過金字塔框架用底層去證明頂層正確。所以到寫測試時已經不知道該怎麼辦了。程式無法被驗證完全正確。
第二類,認為test驅動開發過程寫test和spec部分過於繁瑣。
相對寫一個優秀的test,可debug的程式碼操作起來更簡單,甚至有時候能一眼看破,故寫完spec後順手就寫上了對應的程式碼。導致寫test前就已經把程式碼實現了並且沒有已知bug,於是test工作變的冗餘繁瑣,於是有的開發者為減少冗餘可能實現測試時就不是按照spec來的,而是參照已經寫好的程式碼來的,只是重複一下自己的確認過程,導致測試被簡化,許多問題可能無法被發現。
以上兩種情況都沒有嚴格的按照test驅動方法的順序或細節去實現,於是往往test設計與檢驗環節出現一定的問題,test起不到一個代替客戶檢驗程式的作用,程式的正確性也無法得到驗證。
三.解決的辦法
我個人覺得,如果要讓開發者做到能比較好地接受Test驅動開發流程,自覺地按照步驟來做,需要開發者理解兩點。
一,“端正態度”——認清開發過程的核心與次要。
開發過程中,約束規則的確定和測試的構建才是開發的核心內容,實現程式碼只是次要工作。
給出一個合理的架構等價於給出了一個可行的方法 。它將所要涉及的操作全部描述清楚,剩下的只需要按照它的要求來實現就可以了。這時候寫程式碼的工作是任何一個會寫程式設計語言的人就可以做的簡單操作,他只要機械地執行要求即可。
給出一個充分的測試環境等價於給出了一個判斷程式碼實現是否有效的方法 。它可以輕易證明程式碼是否可行,將驗證程式碼變成傻瓜操作。同時它可以從邏輯上證明程式安全正確。
所以以上兩個工作其實都是實際去開發程式碼的前驅工作,優秀的spec和測試會讓程式碼開發變得簡單而迅速。然而不合理的架構和測試會惡化開發過程,盲目的程式碼開發只能寫出存在風險,未知的,不可靠的程式碼。對於客戶,這種不可信程式碼,與垃圾無異。
所以如果我們有10份的時間精力,我們應當要投5份給spec相關工作,投4份給測試工作,只把最後的一份用於傻瓜般的程式碼開發。
二,“突破束縛”——學習規則,駕馭規則。
在寫低層ADT的時候,方法前後置條件怎麼描述才合理?寫test strategy到底該不該描述一個感覺直觀到像廢話的規則呢?rep感覺沒有限制,那rep invariant那裡填什麼呢?......
你是否碰見過這樣的問題,這些老師課堂上沒講,百度上又不好查的規則性問題 是否給你帶來過困惑?
實際上,如果一個程式設計師在測試階段和構建spec階段總是被類似的規則問題困擾,那麼他心中一定會有種被這些“條條框框”縛住手腳的痛苦,從而不願意採取正確的開發步驟。因此我們要解決這個問題,就需要學習這些規則,從而駕馭他們。
這些“文字規則” 的設計本意都是輔助 你去更好地規避風險完成你的開發的。所以並不會因為你的spec格式寫的不好看而導致你開發失敗,也不會因為你把不需要的文字輔助留作空白而導致程式崩潰。這些只是幫助你設計架構時考慮更全面更細緻。所以你完全可以在這些硬性文字輔助要求的基礎上結合自己開發風格,給出一種你的描述。一切只要能描述清楚即可。
任何一個人都能說出上面的一段話。
但是問題往往就在於我們不知道哪種描述是大家都看得懂的,哪種描述是又簡潔又清楚的。
故從實際出發為了解決這個實際問題,我強烈建議大家去翻看java SDK中的原始碼,尤其推薦自帶ADT的各種原始碼(Integer,String,Boolean,Char......),當你去一個個翻出來看的時候,觀察大佬們怎麼實現每段的文字規則描述後,自然就會了。唯有多練才能駕馭規則。程式碼如此,文件亦如此。
附上檢視原始碼教程:https://blog.csdn.net/sinat_21843047/article/details/80291766