測試驅(qū)動(dòng)開發(fā)
來源:塔塔 更新時(shí)間:2015-06-16
測試驅(qū)動(dòng)開發(fā),英文全稱Test-Driven Development,簡稱TDD,是一種不同于傳統(tǒng)軟件開發(fā)流程的新型的開發(fā)方法。它要求在編寫某個(gè)功能的代碼之前先編寫測試代碼,然后只編寫使測試通過的功能代碼,通過測試來推動(dòng)整個(gè)開發(fā)的進(jìn)行。這有助于編寫簡潔可用和高質(zhì)量的代碼,并加速開發(fā)過程。
Kent Beck先生最早在其極限編程(XP)方法論中,向大家推薦“測試驅(qū)動(dòng)”這一最佳實(shí)踐,還專門撰寫了《測試驅(qū)動(dòng)開發(fā)》一書,詳細(xì)說明如何實(shí)現(xiàn)。經(jīng)過幾年的迅猛發(fā)展,測試驅(qū)動(dòng)開發(fā)已經(jīng)成長為一門獨(dú)立的軟件開發(fā)技術(shù),其名氣甚至蓋過了極限編程。
基本原理
測試驅(qū)動(dòng)開發(fā)的基本思想就是在開發(fā)功能代碼之前,先編寫測試代碼,然后只編寫使測試通過的功能代碼,從而以測試來驅(qū)動(dòng)整個(gè)開發(fā)過程的進(jìn)行。這有助于編寫簡潔可用和高質(zhì)量的代碼,有很高的靈活性和健壯性,能快速響應(yīng)變化,并加速開發(fā)過程。
測試驅(qū)動(dòng)開發(fā)的基本過程如下:
① 快速新增一個(gè)測試
② 運(yùn)行所有的測試(有時(shí)候只需要運(yùn)行一個(gè)或一部分),發(fā)現(xiàn)新增的測試不能通過
③ 做一些小小的改動(dòng),盡快地讓測試程序可運(yùn)行,為此可以在程序中使用一些不合情理的方法
④ 運(yùn)行所有的測試,并且全部通過
⑤ 重構(gòu)代碼,以消除重復(fù)設(shè)計(jì),優(yōu)化設(shè)計(jì)結(jié)構(gòu)
簡單來說,就是不可運(yùn)行/可運(yùn)行/重構(gòu)——這正是測試驅(qū)動(dòng)開發(fā)的口號(hào)。
一個(gè)生動(dòng)比喻
舉個(gè)比較生動(dòng)的例子,這個(gè)例子你一定已經(jīng)在很多關(guān)于TDD的文獻(xiàn)資料上都看到過,但它確實(shí)是一個(gè)不錯(cuò)的比喻。在此我進(jìn)行了一些加工和擴(kuò)展。
蓋房子的時(shí)候,工人師傅砌墻,會(huì)先用樁子拉上線,以使磚能夠壘的筆直,因?yàn)閴敬u的時(shí)候都是以這根線為基準(zhǔn)的。TDD就像這樣,先寫測試代碼,就像工人師傅先用樁子拉上線,然后編碼的時(shí)候以此為基準(zhǔn),只編寫符合這個(gè)測試的功能代碼。
而一個(gè)新手或菜鳥級(jí)的小師傅,卻可能不知道拉線,而是直接把磚往上壘,壘了一些之后再看是否筆直,這時(shí)候可能會(huì)用一根線,量一下砌好的墻是否筆直,如果不直再進(jìn)行校正,敲敲打打。使用傳統(tǒng)的軟件開發(fā)過程就像這樣,我們先編碼,編碼完成之后才寫測試程序,以此檢驗(yàn)已寫的代碼是否正確,如果有錯(cuò)誤再一點(diǎn)點(diǎn)修改。
你是希望先砌墻再拉線,還是希望先拉線再砌墻呢?如果你喜歡前者,那就算了,而如果你喜歡后者,那就轉(zhuǎn)入TDD陣營吧!詳細(xì)可參閱。
本質(zhì)和優(yōu)勢
或許只有了解了測試驅(qū)動(dòng)開發(fā)的本質(zhì)和優(yōu)勢之后,你才會(huì)領(lǐng)略到她的無窮魅力。 測試驅(qū)動(dòng)開發(fā)不是一種測試技術(shù),它是一種分析技術(shù)、設(shè)計(jì)技術(shù),更是一種組織所有開發(fā)活動(dòng)的技術(shù)。相對(duì)于傳統(tǒng)的結(jié)構(gòu)化開發(fā)過程方法,它具有以下優(yōu)勢:
1) TDD根據(jù)客戶需求編寫測試用例,對(duì)功能的過程和接口都進(jìn)行了設(shè)計(jì),而且這種從使用者角度對(duì)代碼進(jìn)行的設(shè)計(jì)通常更符合后期開發(fā)的需求。因?yàn)殛P(guān)注用戶反饋,可以及時(shí)響應(yīng)需求變更,同時(shí)因?yàn)閺氖褂谜呓嵌瘸霭l(fā)的簡單設(shè)計(jì),也可以更快地適應(yīng)變化。
2) 出于易測試和測試獨(dú)立性的要求,將促使我們實(shí)現(xiàn)松耦合的設(shè)計(jì),并更多地依賴于接口而非具體的類,提高系統(tǒng)的可擴(kuò)展性和抗變性。而且TDD明顯地縮短了設(shè)計(jì)決策的反饋循環(huán),使我們幾秒或幾分鐘之內(nèi)就能獲得反饋。
3) 將測試工作提到編碼之前,并頻繁地運(yùn)行所有測試,可以盡量地避免和盡早地發(fā)現(xiàn)錯(cuò)誤,極大地降低了后續(xù)測試及修復(fù)的成本,提高了代碼的質(zhì)量。在測試的保護(hù)下,不斷重構(gòu)代碼,以消除重復(fù)設(shè)計(jì),優(yōu)化設(shè)計(jì)結(jié)構(gòu),提高了代碼的重用性,從而提高了軟件產(chǎn)品的質(zhì)量。
4) TDD提供了持續(xù)的回歸測試,使我們擁有重構(gòu)的勇氣,因?yàn)榇a的改動(dòng)導(dǎo)致系統(tǒng)其他部分產(chǎn)生任何異常,測試都會(huì)立刻通知我們。完整的測試會(huì)幫助我們持續(xù)地跟蹤整個(gè)系統(tǒng)的狀態(tài),因此我們就不需要擔(dān)心會(huì)產(chǎn)生什么不可預(yù)知的副作用了。
5) TDD所產(chǎn)生的單元測試代碼就是最完美的開發(fā)者文檔,它們展示了所有的API該如何使用以及是如何運(yùn)作的,而且它們與工作代碼保持同步,永遠(yuǎn)是最新的。
6) TDD可以減輕壓力、降低憂慮、提高我們對(duì)代碼的信心、使我們擁有重構(gòu)的勇氣,這些都是快樂工作的重要前提。
7)快速的提高了開發(fā)效率
現(xiàn)狀和前景
測試驅(qū)動(dòng)開發(fā)的技術(shù)已得到越來越廣泛的重視,但由于發(fā)展時(shí)間不長,相關(guān)應(yīng)用并不是很成熟?,F(xiàn)今越來越多的公司都在嘗試實(shí)踐測試驅(qū)動(dòng)開發(fā),但由于測試驅(qū)動(dòng)開發(fā)對(duì)開發(fā)人員要求比較高,更與開發(fā)人員的傳統(tǒng)思維習(xí)慣相違背,因此實(shí)踐起來有一定困難。 美國不少著名軟件公司如IBM很早就開始向敏捷轉(zhuǎn)型,在此過程中,TDD通常是最重要也最艱難的一個(gè),正如IBM開發(fā)轉(zhuǎn)型部門副總裁Sue Mckinney所言:測試驅(qū)動(dòng)開發(fā)前景非常誘人,但是“在這個(gè)過程中我們的付出可能也是最多的?!盕orrester的高級(jí)分析師Dave West認(rèn)為,測試驅(qū)動(dòng)開發(fā)(TDD)就像是“圣杯”,但是“如果能達(dá)到這個(gè)目標(biāo),付出再多的辛苦也是值得的?!?
我想,測試驅(qū)動(dòng)開發(fā)的推廣過程中,首要的問題是將開發(fā)人員長期以來形成的思維觀念和意識(shí)形態(tài)轉(zhuǎn)變過來,開發(fā)人員只喜歡編碼,不喜歡測試,更無法理解為什么沒有產(chǎn)品代碼的時(shí)候就先寫單元測試;其次是相關(guān)的技術(shù)支持,測試驅(qū)動(dòng)開發(fā)對(duì)開發(fā)人員提出了更高的要求,不僅要掌握測試和重構(gòu),還要懂得設(shè)計(jì)模式等設(shè)計(jì)方面的知識(shí)。
正像每種革命性的產(chǎn)物剛剛產(chǎn)生之初所必然要經(jīng)歷的艱難歷程,測試驅(qū)動(dòng)開發(fā)也正在經(jīng)歷著,但她正在逐漸走向成熟,前途一片光明。相信未來幾年內(nèi),國內(nèi)的一定會(huì)越來越多的軟件企業(yè)開始普及測試驅(qū)動(dòng)開發(fā)。
關(guān)鍵詞:敏捷開發(fā),測試驅(qū)動(dòng)開發(fā)