皇家方舟

          TDD學(xué)習(xí)心得

          TDD 的總結(jié)

          				
          						讀完TDD(測(cè)試驅(qū)動(dòng)開(kāi)發(fā)),發(fā)現(xiàn)其中主要就是在反復(fù)說(shuō)了這么兩件事情(也就是兩個(gè)簡(jiǎn)單的規(guī)則):一、在寫(xiě)任何代碼之前,寫(xiě)一個(gè)會(huì)失敗的自動(dòng)測(cè)試程序,即單元測(cè)試;二、消除重復(fù)設(shè)計(jì),優(yōu)化設(shè)計(jì)結(jié)構(gòu),即重構(gòu)。整本書(shū)都圍繞著這兩個(gè)規(guī)則來(lái)進(jìn)行說(shuō)明,告訴讀者到底要如何這樣做?又如何分階段應(yīng)用這些規(guī)則?這兩條簡(jiǎn)單的規(guī)則可以運(yùn)用多深?
          				
          		
          				
          						第一部分通過(guò)一個(gè)簡(jiǎn)單的實(shí)例來(lái)告訴讀者如何使用TDD,如何反復(fù)通過(guò)不可運(yùn)行/可運(yùn)行/重構(gòu)/不可運(yùn)行/可運(yùn)行/重構(gòu)來(lái)進(jìn)行開(kāi)發(fā);第二部分告訴讀者如何使用單元測(cè)試,怎樣組織單元測(cè)試;第三部分則是將TDD分解成較小的步驟來(lái)進(jìn)行詳細(xì)說(shuō)明,根據(jù)我對(duì)本書(shū)的理解,我認(rèn)為需要完全將TDD運(yùn)用到日常的開(kāi)發(fā)行為中,則要按照以下非常細(xì)小的步驟進(jìn)行:
          				
          		

          1.?????? 獲得任務(wù)。即項(xiàng)目經(jīng)理安排的任務(wù)。任務(wù)往往不止一項(xiàng)。將它們寫(xiě)入周工作計(jì)劃表或者月工作計(jì)劃表。

          2.?????? 選擇任務(wù)。每天開(kāi)始工作之前,將今天將要解決的問(wèn)題寫(xiě)入工作計(jì)劃列表。并選擇自己最有把握完成的任務(wù)作為當(dāng)前任務(wù)。

          3.?????? 分析并分解任務(wù)。將當(dāng)前任務(wù)分解成一個(gè)個(gè)相對(duì)簡(jiǎn)單的問(wèn)題,分解的問(wèn)題最好是能在十多分鐘之內(nèi)能完成,并將它們寫(xiě)入工作列表。如:若要實(shí)現(xiàn)多幣種相加,則可以分解為:實(shí)現(xiàn)相同幣種之間的相加,不同幣種之間的互換,最后才能實(shí)現(xiàn)不同幣種之間的相加。

          4.?????? 寫(xiě)測(cè)試列表。將分解后的問(wèn)題所對(duì)應(yīng)的測(cè)試寫(xiě)入測(cè)試列表。

          5.?????? 選擇測(cè)試。從測(cè)試列表中選擇自己認(rèn)為最有把握實(shí)現(xiàn)的一項(xiàng)。如:“同幣種相加”對(duì)我來(lái)說(shuō)是最有把握實(shí)現(xiàn)的一項(xiàng),因此我最先來(lái)實(shí)現(xiàn)它,即先從它的測(cè)試程序開(kāi)始編寫(xiě)。

          6.?????? 編寫(xiě)測(cè)試數(shù)據(jù)。寫(xiě)一個(gè)容易讓人理解的必須實(shí)現(xiàn)的測(cè)試數(shù)據(jù)列表,盡量使用顯然數(shù)據(jù)。如:用 String 表示 IP 地址 "255.255.255.255" 轉(zhuǎn)換為 int ,在我們寫(xiě)測(cè)試數(shù)據(jù)時(shí)應(yīng)這樣寫(xiě): (255 << 24) + (255 << 16) + (255 << 8) + 255 ,而不是寫(xiě)“ -1 ”。

          7.?????? 編寫(xiě)測(cè)試。選擇一項(xiàng)最容易讓測(cè)試通過(guò)的測(cè)試數(shù)據(jù)加入測(cè)試方法。斷言?xún)?yōu)先,然后加入為了讓斷言通過(guò)編譯的一切準(zhǔn)備條件。

          8.?????? 運(yùn)行測(cè)試,不可運(yùn)行狀態(tài)。

          9.?????? 編寫(xiě)方法注釋?zhuān)阉邢氲降脑摲椒ㄒ獙?shí)現(xiàn)的功能寫(xiě)上。

          10.?? 編寫(xiě)功能代碼,使之達(dá)到可運(yùn)行狀態(tài)。

          11.?? 重構(gòu),消除重復(fù)設(shè)計(jì)。

          12.?? 往測(cè)試方法中增加一個(gè)新的小測(cè)試。

          13.?? 運(yùn)行測(cè)試,不可運(yùn)行狀態(tài)。

          14.?? 修改功能代碼,使之達(dá)到可運(yùn)行狀態(tài)。

          15.?? 重構(gòu)。消除重復(fù)設(shè)計(jì)。

          16.?? 重復(fù) 12-15

          17.?? 當(dāng)無(wú)論如何也不能讓該測(cè)試通過(guò)的時(shí)候,認(rèn)真想一想是不是哪里出大問(wèn)題了,如果實(shí)在想不出來(lái)的話,就將現(xiàn)有代碼扔掉,重新開(kāi)始。

          18.?? 所有測(cè)試都運(yùn)行通過(guò)之后,仔細(xì)檢查所有代碼,看是否還有值得重構(gòu)的地方,并重構(gòu)。

          19.?? 提交 (check in)

          20.?? 再選擇測(cè)試列表中的下一個(gè)測(cè)試。重復(fù)以上步驟。

          21.?? 當(dāng)一天的工作結(jié)束時(shí),若有某個(gè)任務(wù)未完成,則留下一個(gè)不完整測(cè)試,以便于次日能迅速回憶起當(dāng)時(shí)寫(xiě)該代碼時(shí)的想法,并接著寫(xiě)下去。

          ?

          ?

          ?

          				
          						以下是我對(duì)本書(shū)中某些觀點(diǎn)的看法:
          				
          		
          				
          						
          								1.
          								???? 
          						
          				
          				
          						本書(shū)旨在培訓(xùn)我們具有按照極小的步驟進(jìn)行開(kāi)發(fā),并尋找Bug的能力,并不是說(shuō)一定要按如此小的步驟進(jìn)行。
          				
          		
          				
          						
          								2.
          								???? 
          						
          				
          				
          						書(shū)中所反復(fù)強(qiáng)調(diào)的測(cè)試優(yōu)先斷言?xún)?yōu)先是說(shuō)在功能代碼之前先寫(xiě)測(cè)試,先寫(xiě)斷言,可是反過(guò)頭來(lái),以第一個(gè)測(cè)試來(lái)說(shuō):
          				
          		
          				
          						public void testMutiplication()
          				
          		
          				
          						{
          				
          		
          				
          						Dollar five = new Dollar(5);
          				
          		
          				
          						five.times(2);
          				
          		
          				
          						assertEquals(10,five.amount);
          				
          		
          				
          						}
          				
          		
          				
          						就這個(gè)測(cè)試來(lái)說(shuō),其實(shí)作者在寫(xiě)測(cè)試的時(shí)候也想了很多的問(wèn)題:把這個(gè)測(cè)試放哪?總不可能拿記事本來(lái)寫(xiě)吧!至少該給這個(gè)測(cè)試方法先建立一個(gè)測(cè)試類(lèi)吧!同樣在建立這個(gè)測(cè)試類(lèi)的時(shí)候,是不是也在想著為該類(lèi)命什么樣的名?再進(jìn)一步,我要寫(xiě)測(cè)試方法,在為測(cè)試方法命名的時(shí)候?qū)嶋H上也是在為我們所要寫(xiě)的方法命名,不是么?因此,我覺(jué)得,在我還沒(méi)有達(dá)到Kent Beck的水平之前,我還是會(huì)在寫(xiě)測(cè)試之前先想一想即將要編寫(xiě)的方法應(yīng)歸于哪個(gè)類(lèi),并先將該類(lèi)創(chuàng)建好,再把下一步要編寫(xiě)的方法寫(xiě)好(當(dāng)然此時(shí)肯定也是一個(gè)空方法),同時(shí)把自己所能想到的方法將要實(shí)現(xiàn)的功能(可以是比較粗略的)全部寫(xiě)入方法注釋中,此時(shí)的注釋可以是比較隨意的,因?yàn)樵诎逊椒▽?xiě)完之后還要進(jìn)行重構(gòu)嘛!然后按照注釋中的功能來(lái)編寫(xiě)一個(gè)一個(gè)的測(cè)試方法并完善功能代碼。
          				
          		
          				
          						
          								3.
          								???? 
          						
          				
          				
          						如果按照本書(shū)所說(shuō)的,開(kāi)發(fā)過(guò)程中幾乎沒(méi)有事先的設(shè)計(jì),因?yàn)樽髡哒J(rèn)為良好的設(shè)計(jì)會(huì)在重構(gòu)中逐漸浮出水面的。但是我很清楚,我不是Kent Beck,如果沒(méi)有事先設(shè)計(jì)的話,以我現(xiàn)在的水平,重構(gòu)時(shí)的工作量一定會(huì)非常大;因此如果在寫(xiě)代碼之前花一定的時(shí)間設(shè)計(jì)一下代碼結(jié)構(gòu),可以在一定程度上減小重構(gòu)時(shí)的工作量。并且我認(rèn)為良好的事先設(shè)計(jì)會(huì)為重構(gòu)工作減少很大的工作量,當(dāng)然事先設(shè)計(jì)也不應(yīng)該占有太多的時(shí)間,否則,還不如先寫(xiě)完之后慢慢來(lái)重構(gòu)。
          				
          		
          				
          						
          								4.
          								???? 
          						
          				
          				
          						書(shū)中所說(shuō)的關(guān)注當(dāng)前工作這一點(diǎn)非常好,因?yàn)樵诂F(xiàn)實(shí)工作中,常常會(huì)因?yàn)橄氲脚c當(dāng)前工作相關(guān)的事情可能會(huì)比較多,而往往我們會(huì)丟下手上的工作,先去完成另外一項(xiàng)工作,可是等回到剛才丟下的工作前時(shí)又要花很長(zhǎng)的一段時(shí)間來(lái)回憶當(dāng)時(shí)的情形。因此,我們應(yīng)該學(xué)習(xí)書(shū)中的方法,把新想法記錄下來(lái),等完成當(dāng)前工作后再去考慮。也許有些時(shí)候會(huì)出現(xiàn)這種情況,如果另外一件事情未完成,當(dāng)前工作無(wú)法進(jìn)行的情況不得不打斷當(dāng)前工作,那就不得不將注意力全部轉(zhuǎn)移到另外一件事情上去。但是,如果這種打斷出現(xiàn)多次的時(shí)候,就應(yīng)該認(rèn)真思考自己的分析問(wèn)題的粒度是不是太大了,然后重新去分解問(wèn)題。等問(wèn)題分析到可以不依賴(lài)未編寫(xiě)過(guò)的方法時(shí)再繼續(xù)工作也不遲。這樣只會(huì)提高工作效率和自信心。否則,不停地從當(dāng)前工作中跳出,不僅為影響工作效率,而且會(huì)影響自信心,為什么還有這么多沒(méi)有完成呢?因?yàn)樵谀悴粩嗟靥霎?dāng)前工作后,你就會(huì)留下一個(gè)個(gè)未完成的工作。你的腦子里就會(huì)想著還有多少個(gè)未完成的工作在等著自己去完成。
          						
          								
          								
          						
          				
          		
          				
          						
          								5.
          								???? 
          						
          				
          				
          						留下一個(gè)不完整測(cè)試是在編程期間結(jié)束工作的最好辦法。因?yàn)楫?dāng)測(cè)試運(yùn)行時(shí)沒(méi)出現(xiàn)綠色狀態(tài)條時(shí),會(huì)很容易找到明顯的地方重新開(kāi)始。這一點(diǎn)實(shí)現(xiàn)起來(lái)可能有點(diǎn)困難,但是卻是一個(gè)非常有效的辦法,當(dāng)工作任務(wù)繁多的時(shí)候常常會(huì)忘記昨天做到哪了,今天該從哪做起。
          						
          								
          								
          						
          				
          		
          				
          						
          								6.
          								???? 
          						
          				
          				
          						當(dāng)編寫(xiě)功能代碼時(shí),為了讓測(cè)試通過(guò)可以采取的措施有:顯明實(shí)現(xiàn),偽實(shí)現(xiàn),三角法,從一到多。當(dāng)自己讓該測(cè)試通過(guò)有把握的時(shí)候,即使用顯明實(shí)現(xiàn);若在顯明實(shí)現(xiàn)的過(guò)程中,無(wú)法達(dá)到可運(yùn)行狀態(tài),則返回到之前的可運(yùn)行狀態(tài),采用偽實(shí)現(xiàn)的方法使測(cè)試達(dá)到可運(yùn)行狀態(tài);當(dāng)需要為集合編寫(xiě)測(cè)試的時(shí)候,采用從一到多的方法。如:數(shù)組求和則可以先測(cè)試該數(shù)組中只有一個(gè)元素,再逐漸增加元素進(jìn)行測(cè)試。
          				
          		
          				
          						
          								7.
          								???? 
          						
          				
          				
          						相互獨(dú)立的測(cè)試。即每個(gè)測(cè)試之間必須互不干擾。如果一個(gè)測(cè)試失敗必須只對(duì)應(yīng)一個(gè)問(wèn)題;兩個(gè)失敗就對(duì)應(yīng)兩個(gè)問(wèn)題。測(cè)試之間都不依賴(lài)與運(yùn)行順序,一個(gè)測(cè)試不要因?yàn)榍懊娴臏y(cè)試不存在而失敗。這一點(diǎn)實(shí)現(xiàn)起來(lái)其實(shí)也相當(dāng)?shù)睦щy,因?yàn)楫?dāng)一個(gè)底層函數(shù)的測(cè)試失敗時(shí),其上層函數(shù)(即調(diào)用了它的那些函數(shù))的測(cè)試程序都可能會(huì)失敗,因此很難做到一個(gè)失敗的測(cè)試對(duì)應(yīng)一個(gè)問(wèn)題。
          				
          		
          				
          						
          								8.
          								???? 
          						
          				
          				
          						當(dāng)在編寫(xiě)代碼時(shí),當(dāng)?shù)谝淮螠?zhǔn)備使用某個(gè)包內(nèi)的某項(xiàng)新功能時(shí),為其編寫(xiě)測(cè)試,即學(xué)習(xí)測(cè)試。看它是否滿(mǎn)足我們期望的要求。并且必須在其符合我們的期望要求時(shí)我們才可以在程序中使用它。
          				
          		
          				
          						
          								9.
          								???? 
          						
          				
          				
          						當(dāng)每新建一個(gè)包時(shí),即新建一個(gè)AllTests類(lèi)用于測(cè)試該包中所有測(cè)試類(lèi)。在每寫(xiě)一個(gè)測(cè)試類(lèi)時(shí),先將public static Test suite()寫(xiě)好,并把該測(cè)試類(lèi)加入到包中的AllTests中,隨時(shí)確保包AllTests中包含了包中的所有測(cè)試程序。
          				
          		
          				
          						
          								10.
          								? 
          						
          				
          				
          						需要重點(diǎn)掌握的重構(gòu)方法(即常用的重構(gòu))有:重命名,提取方法,添加參數(shù),刪除參數(shù),方法內(nèi)聯(lián),提煉方法對(duì)象,消除臨時(shí)變量,提取匿名類(lèi),分離內(nèi)部類(lèi)等等。
          				
          		
          				
          						
          								11.
          								? 
          						
          				
          				
          						在我們工作的過(guò)程中,很多時(shí)候會(huì)遇到一些很困難的問(wèn)題,在反反復(fù)復(fù)思考許多遍還是想不到解決的辦法,往往這樣的情況是我們的思維陷入了錯(cuò)誤的陷阱里,在這個(gè)時(shí)候我們可以選擇休息一會(huì),喝一杯茶,走動(dòng)一下。拋開(kāi)那些剛才所做的事情。如果在休息了多次之后還沒(méi)有想到解決方案,就扔掉這些代碼,重新開(kāi)始。
          				
          		

          ?

          ?



          posted on 2006-11-06 09:15 阿輝 閱讀(486) 評(píng)論(1)  編輯  收藏 所屬分類(lèi): 學(xué)習(xí)日志

          Feedback

          # 代碼中的重復(fù) 2006-11-10 10:00 阿輝

            程序代碼中重復(fù)無(wú)處不在,重構(gòu)即要消除重復(fù),代碼中多次出現(xiàn)過(guò)的語(yǔ)句、模塊、流程等是重復(fù),當(dāng)我們對(duì)代碼做一定的修改時(shí),需要對(duì)其它地方進(jìn)行相應(yīng)的修改,這種情況也是重復(fù)。因此在寫(xiě)代碼時(shí),先想一想修改該代碼后,是否會(huì)對(duì)程序的其它地方造成影響,在有單元測(cè)試支持的情況下,可以在修改之后運(yùn)行一下單元測(cè)試,看是否還是可運(yùn)行狀態(tài)。若因?yàn)榇颂幮薷亩斐蓡卧獪y(cè)試變成了不可運(yùn)行狀態(tài),則此代碼必然與系統(tǒng)中的某處存在依賴(lài)關(guān)系(即有重復(fù)存在),因此要一定想辦法在消除該重復(fù)之后再進(jìn)行下一步工作,若無(wú)法解決該問(wèn)題則需要將此情況記錄下來(lái)。
            回復(fù)  更多評(píng)論   


          My Links

          Blog Stats

          常用鏈接

          留言簿(1)

          隨筆分類(lèi)

          隨筆檔案

          搜索

          積分與排名

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 巩义市| 准格尔旗| 巴林右旗| 涡阳县| 邢台县| 信丰县| 常州市| 屏山县| 什邡市| 太湖县| 襄汾县| 德清县| 米易县| 玛沁县| 霸州市| 绩溪县| 株洲市| 大宁县| 通化县| 铜鼓县| 江陵县| 汉川市| 郴州市| 青神县| 浏阳市| 昌图县| 凤台县| 浙江省| 文成县| 威宁| 达孜县| 肥西县| 秦安县| 奉节县| 黑龙江省| 汉中市| 洞头县| 济源市| 伊宁县| 宁晋县| 上杭县|