1. 起步 - 從哪里開始没龙?
萬事開頭難铺厨。不過如果有人拿一個(gè)例子,一步一步演示給你看硬纤,那就不難解滓。Kent Beck在《測試驅(qū)動(dòng)開發(fā)》一書中就這樣做了。這本書很薄咬摇,但它是給初學(xué)者準(zhǔn)備的極好的入門書。雖然書中的例子是用Java演示的煞躬,但C++的學(xué)習(xí)者理解起來也沒有什么難度肛鹏。
書中使用了“多幣種資金(Multi-Currency Money)”的例子,需要考慮多幣種恩沛,匯率等多種情況在扰,剛好能演示如何分解復(fù)雜的任務(wù),又不會(huì)讓讀者厭煩雷客。在逐步達(dá)到目標(biāo)的過程中芒珠,我們能看到:
- “先寫測試,再實(shí)現(xiàn)”的工作方式吧碾。以測試用例為單位宪祥,培養(yǎng)“小步前進(jìn)”的節(jié)奏感官卡。
- 從一個(gè)大任務(wù)中切下一組小任務(wù),逐步實(shí)現(xiàn)娜汁,逐步接近目標(biāo)。
- 小心構(gòu)造測試用例兄朋,持續(xù)運(yùn)行自動(dòng)測試集掐禁,保證代碼持續(xù)可靠。
- 容忍中間過程的不完美,將它看成一個(gè)持續(xù)完善的過程傅事;同時(shí)保持對壞氣味(bad smell)的敏銳度缕允,挑選適當(dāng)?shù)臅r(shí)機(jī)消除它,得到整潔的代碼蹭越。在容忍和不容忍兩者中達(dá)到平衡障本。
- 清晰的設(shè)計(jì)和可靠的代碼,是產(chǎn)生自信的土壤般又,而自信會(huì)激發(fā)人的靈感彼绷。抓住突然涌現(xiàn)到頭腦中的靈感,對設(shè)計(jì)做出優(yōu)化調(diào)整茴迁。
- 從使用者的角度審視接口寄悯,給接口塑形(Shape)。首先考慮“我想要什么樣的“堕义,而不是“我能做什么樣的”猜旬。
測試驅(qū)動(dòng)開發(fā)需要選擇合適的自動(dòng)化測試框架。 CPPUnit 和 Google Test都可以倦卖。
既然定位自己是C++開發(fā)者洒擦,適當(dāng)理解C++的常用法還是必要的。如果經(jīng)常還在語法上打轉(zhuǎn)怕膛,那積極性自然會(huì)打些折熟嫩。這里是一些有用的C++參考書。
2. 夯基礎(chǔ) - 測試驅(qū)動(dòng)方法 + 設(shè)計(jì)模式
練習(xí)了一些小例子褐捻,學(xué)會(huì)了基本的步驟后掸茅,需要復(fù)雜一些的東西來錘煉我們的頭腦。一個(gè)好的方法是在實(shí)際的項(xiàng)目中嘗試運(yùn)用《設(shè)計(jì)模式》一書中描述的模式柠逞。
選擇第一個(gè)項(xiàng)目很重要昧狮。如果第一次取得了明顯的收益,就會(huì)產(chǎn)生更多的興趣板壮,并一再嘗試逗鸣。如果沒有收益,就可能產(chǎn)生不過如此的情緒绰精,最后的結(jié)果就是繼續(xù)不下去撒璧。
首選是邏輯復(fù)雜,環(huán)境依賴度小的項(xiàng)目笨使,這樣的項(xiàng)目特別能體現(xiàn)測試驅(qū)動(dòng)開發(fā)的優(yōu)勢沪悲。其次是環(huán)境容易抽象,適合用Mock Object模擬的項(xiàng)目阱表。
這一階段的目標(biāo)是:在測試驅(qū)動(dòng)開發(fā)的輔助下殿如,運(yùn)用設(shè)計(jì)模式贡珊,將復(fù)雜的邏輯表達(dá)得清楚明白,容易理解涉馁。
一部分設(shè)計(jì)模式容易找到適合運(yùn)用的場景门岔,如Builder, Template Method, Composite,Decorator等烤送,另外一些則不容易寒随,如Prototype, Mediator等。還有一個(gè)是使用很廣帮坚,卻與測試驅(qū)動(dòng)開發(fā)不兼容的妻往,就是Singleton,因?yàn)樗鼤?huì)導(dǎo)致測試用例之間的狀態(tài)殘留试和,讓人厭煩讯泣。
設(shè)計(jì)模式是不是實(shí)用,用上了才知道阅悍,也只有用上了好渠,解決問題了,才算理解了节视。沒定下來前就需要嘗試拳锚,很可能走到后面發(fā)現(xiàn)走錯(cuò)了,要退回去寻行。所以有個(gè)工具必不可少霍掺,就是帶分支特性的版本控制系統(tǒng)“柚總是在分支上嘗試杆烁,隨便試。搞砸了拦坠,放棄這個(gè)分支就是了连躏。
這樣的工具以前是CVS剩岳,現(xiàn)在GIT替代了它的位置贞滨,因?yàn)?a target="_blank">分支是GIT的天性。
DVR-POS庫是測試驅(qū)動(dòng)開發(fā)的一個(gè)實(shí)際項(xiàng)目的例子拍棕。
3. 晉級(jí) - 從項(xiàng)目需求出發(fā)考慮: “需要怎樣的晓铆?怎樣設(shè)計(jì)能滿足?”
將模式運(yùn)用到項(xiàng)目是一種正向的思考绰播,我們現(xiàn)在需要反向的思考骄噪。把模式放一邊,專注于項(xiàng)目本身有什么問題蠢箩,怎樣的設(shè)計(jì)能解決這個(gè)問題链蕊。
在思考的過程中事甜,模式會(huì)自然而然地蹦出來。呀滔韵!這個(gè)模式就是用來解決這類問題的逻谦!或者,這個(gè)設(shè)計(jì)不就是這個(gè)模式嘛陪蜻!這時(shí)邦马,就會(huì)有一種與大師心心相通的感覺。
這個(gè)時(shí)候宴卖,設(shè)計(jì)模式已經(jīng)開始成為我們頭腦的一部分了滋将。如果在前一階段還需要把《設(shè)計(jì)模式》放在桌面當(dāng)工具書,那么現(xiàn)在可以把它放回到書架上了症昏。具體的條條框框已經(jīng)忘掉了随闽,留在腦子里的只是一些模糊的概念。但是當(dāng)問題冒出來的時(shí)候齿兔,其中的部分概念就會(huì)重新組合起來橱脸,成為解決問題的利器。
這個(gè)時(shí)候分苇,已經(jīng)不再拘束于模式的已有用法添诉,也不再拘束于已有的模式,甚至也不再拘束于模式了医寿。很多時(shí)候栏赴,簡單的OO就夠了,那就OO好了靖秩。簡單的一擊致命才是最漂亮的劍法须眷。
測試驅(qū)動(dòng)開發(fā)的基本原則是“大膽設(shè)想,小步前進(jìn)”沟突』牛“小步前進(jìn)”已經(jīng)成為基本的工作節(jié)奏了,這個(gè)階段的重點(diǎn)是“大膽設(shè)想”惠拭。
軟件的目標(biāo)系統(tǒng)有它運(yùn)行的邏輯扩劝,而設(shè)計(jì)的目標(biāo)就是尋找最恰當(dāng)?shù)乇磉_(dá)這個(gè)邏輯的方式。這里需要各種可能的嘗試职辅,包括頭腦層面的棒呛,稿紙層面的,乃至寫代碼層面的域携,直到找到不湊合簇秒,不勉強(qiáng),不留一點(diǎn)別扭的設(shè)計(jì)秀鞭。
在這個(gè)嘗試的過程中趋观,設(shè)計(jì)和編碼會(huì)更大幅度地變動(dòng)扛禽。自動(dòng)化測試框架,和持續(xù)運(yùn)行的測試用例集就更不能缺了皱坛。
在實(shí)際的項(xiàng)目中旋圆,對優(yōu)美設(shè)計(jì)的追求,總是與趕進(jìn)度的壓力并存麸恍,所以這時(shí)做好心理的建設(shè)非常重要灵巧。除了強(qiáng)大的心理承受能力之外,還得有對項(xiàng)目前景的預(yù)見性抹沪。經(jīng)常需要做決定刻肄,是奮勇向前,還是暫時(shí)妥協(xié)融欧?抽點(diǎn)時(shí)間讀一讀這本《OO項(xiàng)目求生法則》可以幫到我們敏弃。
JSON過濾庫是測試驅(qū)動(dòng)開發(fā)的又一個(gè)實(shí)際項(xiàng)目的例子。
4. 自由王國 - 將設(shè)計(jì)模式的運(yùn)用擴(kuò)展到整個(gè)項(xiàng)目
評價(jià)一個(gè)方法是否適合的一個(gè)重要標(biāo)準(zhǔn)噪馏,是它是不是能帶來遠(yuǎn)超付出的收益麦到。所以測試驅(qū)動(dòng)開發(fā)并不是適合所有的項(xiàng)目。一些對環(huán)境高度依賴的代碼就是這樣欠肾,比如socket編程瓶颠,數(shù)據(jù)庫編程等,這些領(lǐng)域的測試用例都依賴人工執(zhí)行刺桃。Mock Object能用于模擬環(huán)境粹淋,但并不適合測試環(huán)境本身。
測試驅(qū)動(dòng)開發(fā)在這里的意義在于瑟慈,用它訓(xùn)練出來的頭腦已經(jīng)能輕松應(yīng)對這些挑戰(zhàn)了桃移。這個(gè)頭腦能:
- 敏銳地識(shí)別和整理出有條理和完善的測試集。它與自動(dòng)測試集很類似葛碧,區(qū)別只是它是手工執(zhí)行借杰。回歸檢查慢一點(diǎn)进泼,總還是能做的蔗衡。
- 靈活自如地找到恰當(dāng)?shù)脑O(shè)計(jì)。恰當(dāng)?shù)剡x擇設(shè)計(jì)模式自然也不在話下缘琅。
5. 超越 - 從軟件項(xiàng)目聯(lián)想到其他領(lǐng)域
這個(gè)階段是務(wù)虛的粘都,但卻是有意義的升華廓推。
Alexander在建筑領(lǐng)域總結(jié)了模式語言刷袍,《設(shè)計(jì)模式》的作者在軟件領(lǐng)域也總結(jié)了類似的思想,哲學(xué)上這兩個(gè)領(lǐng)域是相通的樊展。同樣的呻纹,它們與其他領(lǐng)域也是相通的堆生。
這個(gè)世界以某種符合邏輯的方式組織在一起,我們窮盡一生去摸索雷酪,試圖搞清楚組織的規(guī)律淑仆,給出它如何運(yùn)行的解釋。想不到困惑哥力,想到了就豁然開朗蔗怠。這里想到的就是某種模式。但我們接觸的范圍總在拓展吩跋,所以固守有限的模式顯然不夠寞射。
從模式起步,成長锌钮,最終還要超越模式桥温。就如同張無忌練太極劍法一樣,從“劍招”開始梁丘,還要超越它侵浸,悟到“劍意”。
只聽張三豐問道:“孩兒氛谜,你看清楚了沒有掏觉?”張無忌道:“看清楚了≈德”張三豐道:“都記得了沒有履腋?”
張無忌道:“已忘記了一小半〔严”張三豐道:“好遵湖,那也難為了你。你自己去想想罷晚吞⊙泳桑”張無忌低頭默想。
過了一會(huì)槽地,張三豐問道:“現(xiàn)下怎樣了迁沫?”張無忌道:“已忘記了一大半“莆茫”
周顛失聲叫道:“糟糕集畅!越來越忘記得多了。張真人缅糟,你這路劍法是很深?yuàn)W挺智,看一遍怎能記得?
請你再使一遍給我們教主瞧瞧罷窗宦∩馄模”張三豐微笑道:“好二鳄,我再使一遍∶角樱”提劍出招订讼,演將起來。眾人只
看了數(shù)招扇苞,心下大奇欺殿,原來第二次所使,和第一次使的竟然沒一招相同鳖敷。周顛叫道:“糟糕祈餐,糟糕!
這可更加叫人胡涂啦哄陶》簦”張三豐畫劍成圈,問道:“孩兒屋吨,怎樣啦蜒谤?”張無忌道:“還有三招沒忘記≈寥牛”
張三豐點(diǎn)點(diǎn)頭鳍徽,放劍歸座。張無忌在殿上緩緩踱了一個(gè)圈子敢课,沉思半晌阶祭,又緩緩踱了半個(gè)圈子,抬起
頭來直秆,滿臉喜色濒募,叫道:“這我可全忘了,忘得乾乾凈凈的了圾结」逄辏”張三豐道:“不壞,不壞筝野!忘得真快晌姚,
你這就請八臂神劍指教罷!”說著將手中木劍遞了給他歇竟。
......
張無忌這一招乃是以己之鈍挥唠,擋敵之無鋒,實(shí)已得了太極劍法的精奧焕议。要知張三豐傳給他的乃是“劍意”宝磨,
而非“劍招”,要他將所見到的劍招忘得半點(diǎn)不剩,才能得其神髓懊烤,臨敵時(shí)以意馭劍,千變?nèi)f化宽堆,無窮無盡腌紧。
倘若尚有一兩招劍法忘不乾凈,心有拘囿畜隶,劍法便不能純壁肋。
相關(guān)鏈接
測試驅(qū)動(dòng)開發(fā)與設(shè)計(jì)模式 - 為什么使用測試驅(qū)動(dòng)開發(fā)
測試驅(qū)動(dòng)開發(fā)與設(shè)計(jì)模式 - 從入門到精通
測試驅(qū)動(dòng)開發(fā)與設(shè)計(jì)模式 - C++書籍及網(wǎng)站
測試驅(qū)動(dòng)開發(fā)與設(shè)計(jì)模式 - 適應(yīng)并改進(jìn)軟件設(shè)計(jì)過程
測試驅(qū)動(dòng)開發(fā)與設(shè)計(jì)模式 - 讓“理想結(jié)構(gòu)”與“快速變更”并行
測試驅(qū)動(dòng)開發(fā)與設(shè)計(jì)模式 - 提速 — 在紙上做細(xì)節(jié)設(shè)計(jì)
測試驅(qū)動(dòng)開發(fā)與設(shè)計(jì)模式 - 開發(fā)實(shí)例一 DVR-POS庫
測試驅(qū)動(dòng)開發(fā)與設(shè)計(jì)模式 - 開發(fā)實(shí)例二 JSON過濾庫
測試驅(qū)動(dòng)開發(fā)與設(shè)計(jì)模式 - 開發(fā)實(shí)例三 rs_driver庫