L19.3 測試驅(qū)動(dòng)開發(fā)和重構(gòu)和其他內(nèi)容簡介_第1頁
L19.3 測試驅(qū)動(dòng)開發(fā)和重構(gòu)和其他內(nèi)容簡介_第2頁
L19.3 測試驅(qū)動(dòng)開發(fā)和重構(gòu)和其他內(nèi)容簡介_第3頁
L19.3 測試驅(qū)動(dòng)開發(fā)和重構(gòu)和其他內(nèi)容簡介_第4頁
L19.3 測試驅(qū)動(dòng)開發(fā)和重構(gòu)和其他內(nèi)容簡介_第5頁
已閱讀5頁,還剩35頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

系統(tǒng)分析與設(shè)計(jì)

第21章測試驅(qū)動(dòng)開發(fā)和重構(gòu)

目標(biāo)結(jié)合學(xué)習(xí)案例,介紹測試驅(qū)動(dòng)開發(fā)和重構(gòu)這兩種重要的開發(fā)實(shí)踐極限編程(XP)所提倡的重要測試實(shí)踐是:首先編寫測試。它還提倡不斷地重構(gòu)代碼以改進(jìn)質(zhì)量,包括降低冗余、提高清晰度等?,F(xiàn)代工具也都支持這兩種實(shí)踐。21.1測試驅(qū)動(dòng)開發(fā)(TDD)

1.什么是測試驅(qū)動(dòng)開發(fā)

測試驅(qū)動(dòng)開發(fā)是迭代和敏捷XP方法提倡的優(yōu)秀實(shí)踐,也適用于UP,該實(shí)踐也稱測試優(yōu)先開發(fā)。TDD涵蓋單元測試即對構(gòu)件個(gè)體進(jìn)行測試,這里著重介紹對單個(gè)類進(jìn)行單元測試的應(yīng)用。在TDD的OO單元測試中,要在測試類之前編寫測試代碼,并且開發(fā)者要為幾乎所有的產(chǎn)品代碼編寫單元測試代碼。其基本方法是先編寫一小段測試代碼,然后編寫一小段產(chǎn)品代碼保證其通過測試,依此類推。2.測試驅(qū)動(dòng)開發(fā)的優(yōu)點(diǎn)

1)事先編寫單元測試以防止人為地忽略單元測試;2)令人鼓舞的測試不僅可以使程序員獲得滿足感,而且可使程序員意識(shí)到編程的挑戰(zhàn)性;3)堅(jiān)持測試優(yōu)先的原則以避免程序員試圖跳過測試或隨心所欲的測試;4)有助于改善接口和行為的設(shè)計(jì)細(xì)節(jié).因?yàn)闇y試是從實(shí)際需求出發(fā)的,它能指導(dǎo)開發(fā)者如何考慮諸如方法名稱、返回值、參數(shù)和行為等細(xì)節(jié)。5)累積的單元測試代碼能夠提供有意義的正確性驗(yàn)證,而且能夠十分簡便地自動(dòng)運(yùn)行。當(dāng)測試庫累積到一定規(guī)模時(shí),這種投入會(huì)產(chǎn)生重要回報(bào)。

6)當(dāng)測試庫具備一定規(guī)模時(shí),可以測試修改可能導(dǎo)致的問題。當(dāng)開發(fā)者準(zhǔn)備更改現(xiàn)有代碼時(shí),可以運(yùn)行的單元測試集會(huì)發(fā)現(xiàn)你的更改是否會(huì)導(dǎo)致錯(cuò)誤。3.單元測試框架和編寫單元測試的步驟最為流行的單元測試框架是xUnit家族,參見,對于Java,其常用版本是JUnit。也有針對.NET的Nunit等等。大多數(shù)JavaIDE都集成了JUnit,例如Eclipse。遵守如下步驟完成每個(gè)測試方法:

1)創(chuàng)建被測試固件

2)讓它完成你要測試的操作

3)評估結(jié)果是否為期望值4.示例假設(shè)使用JUnit和TDD來創(chuàng)建Sale類。在編寫Sale類之前,我們要在SaleTest類中按照如下步驟編寫單元測試方法:

1)創(chuàng)建Sale---被測試的事物,也稱測試固件(fixture)。

2)使用makeLineItem方法(我們想要測試的public方法)為其增加一些商品條目。

3)請求總計(jì)金額,并且使用assertTrue方法驗(yàn)證是否為期望值。注意:

1)我們并沒有先為Sale編寫所有的單元測試,而只編寫了一個(gè)測試方法,等到在Sale類中實(shí)現(xiàn)該方法并確保通過了測試,然后再反復(fù)這一過程,直到結(jié)束。

2)要使用JUnit,你必須創(chuàng)建并擴(kuò)展JUnit的TestCase類的測試類,這樣測試類才可以繼承各種單元測試的行為。

3)在JUnit中,你要為想要測試的每個(gè)方法創(chuàng)建單獨(dú)的測試方法。但不必為諸如get和Set方法編寫測試方法(通常會(huì)自動(dòng)生成)。例如:

publicclassSaleTestextedsTestCase{//…//測試Sale.makeLineItem方法

publicvoidtestMakeLineItem(){//步驟1:創(chuàng)建測試固件,約定命名為‘fixture’,//通常定義為實(shí)例字段而非局部變量.Salefixture=newSale();//設(shè)置輔助測試的對象

Moneytotal=newMoney(7.5);Moneyprice=newMoney(2.5);ItemIDid=newItemID(1);ProductDescriptiondesc=newProductDescription(id,price,“product1”);//步驟2:執(zhí)行測試方法makeLineItem

fixture.makeLineItem(desc,1);

fixture.makeLineItem(desc,2);//步驟3:評估結(jié)果,驗(yàn)證結(jié)果是否為7.5,

//對于復(fù)雜的評估可能有很多assertTrue語句

assertTrue(sale.getTotal().equals(total));}}

只有在編寫完testMakeLineItem()測試方法之后,才開始編寫Sale.makeLineItem方法,并且要通過這一測試。所以才叫測試驅(qū)動(dòng)開發(fā)或測試優(yōu)先開發(fā)。5.IDE對TDD和xUnit的支持大多數(shù)IDE都會(huì)對xUnit提供支持,例如,Eclipse支持JUnit。其中的JUnit包括可視化的提示,即當(dāng)測試通過后,將會(huì)顯示綠條。由此產(chǎn)生了TDD的一句俗語:保持狀態(tài)條為綠色就是保持代碼的純凈見下圖:21.2重構(gòu)

1.什么是重構(gòu)?

重構(gòu)是重寫或重新構(gòu)建已有代碼的結(jié)構(gòu)化和規(guī)律性方法,但不會(huì)改變已有代碼的外在行為。而是采用一系列少量轉(zhuǎn)換的步驟,并且每一步都結(jié)合了重新執(zhí)行的測試。不斷地重構(gòu)代碼也是XP的一個(gè)實(shí)踐,該實(shí)踐也適用于所有迭代方法,包括UP。重構(gòu)的本質(zhì)是一次實(shí)行一小步保留行為的轉(zhuǎn)化。每次轉(zhuǎn)化都稱為重構(gòu)。每次轉(zhuǎn)化之后要重新執(zhí)行單元測試,以保證重構(gòu)不會(huì)導(dǎo)致錯(cuò)誤。2.重構(gòu)的活動(dòng)和目標(biāo)*去除冗余代碼*改善清晰度*使過長的方法變得較短*去除硬編碼的字面常量*更多…

進(jìn)行良好重構(gòu)的代碼應(yīng)該是簡短、緊湊、清晰的且沒有冗余。不具備這些品質(zhì)的代碼是壞味代碼(codesmell)。壞味代碼不見的就是錯(cuò)誤代碼。惡臭代碼(codestench)是真正要清理的垃圾代碼。

重構(gòu)正是對壞味代碼進(jìn)行矯正。與模式類似,重構(gòu)也有名稱,大約有100多個(gè)已命名的重構(gòu)。例如:*提煉方法(ExtractMethod):將較長的方法轉(zhuǎn)化為較短的方法。*提煉常量(ExtractConstant):使用常量變量替換字面常量。*引入解釋變量…*使用工廠方法代替構(gòu)造器調(diào)用…

等等。

3.示例

1)描述提煉方法示例該示例中所列的Player類中的takeTurn方法,其中在代碼的開始部分完成了拋擲子和在循環(huán)中計(jì)算總點(diǎn)數(shù)的操作。這段代碼本身是獨(dú)立和內(nèi)聚的行為單元,我們可以將這些代碼提煉為私有的幫助者方法rollDice,以使takeTurn變得簡短、清晰,并能更好地支持高內(nèi)聚。注意takeTurn方法中需要rollTotal的值,因此rollDice必須返回rollTotal。重構(gòu)前的takeTurn方法publicclassPlayer{

privatePiecepiece; privateBoardboard; privateDie[]dice; //…publicvoidtakeTurn(){//rolldice introllTotal=0; for(inti=0;i<dice.length;i++) { dice[i].roll(); rollTotal+=dice[i].getFaceValue(); }SquarenewLoc=board.getSquare(piece.getLocation(),rollTotal); piece.setLocation(newLoc);}}//endofclass提煉方法重構(gòu)后的代碼publicclassPlayer{

privatePiecepiece; privateBoardboard; privateDie[]dice; //…publicvoidtakeTurn(){//therefactoredhelpermethod introllTotal=rollDice();SquarenewLoc=board.getSquare(piece.getLocation(),rollTotal); piece.setLocation(newLoc);}privateintrollDice(){

introllTotal=0; for(inti=0;i<dice.length;i++) {

dice[i].roll(); rollTotal+=dice[i].getFaceValue(); } returnrollTotal;}}//endofclass2)引入解釋變量的示例引入解釋變量之前的代碼://goodmethodname,butthelogicofthebodyisnotclearbooleanisLeapYear(intyear){ return (((year%400)==0)|| (((year%4)==0)&&((year%100)!=0)));}引入解釋變量之后的代碼://that’sbetter!booleanisLeapYear(intyear){

booleanisFourthYear=((year%4)==0);booleanisHundrethYear=((year%100)==0);booleanis4HundrethYear=((year%400)==0);return(is4HundrethYear||(isFourthYear&&!isHundrethYear));}4.IDE對重構(gòu)的支持大部分常用的IDE都支持自動(dòng)重構(gòu)。如圖,其中rollDice方法是自動(dòng)生成的。重構(gòu)之前的IDE重構(gòu)之后的IDE第22章UML工具與UML藍(lán)圖

目標(biāo)簡要了解UML的使用方式22.1UML應(yīng)用的三種方式

1.UML作為草圖

2.UML作為藍(lán)圖:適用與代碼和圖形的生成。利用工具,使用相對詳細(xì)的圖形來指導(dǎo)代碼的生成。生成代碼以后,通常還需要開發(fā)人員添加大量細(xì)節(jié)。還可以從代碼生成圖形,用來可視化代碼庫。

3.UML作為編程語言:UML形式的軟件系統(tǒng)的完整的可執(zhí)行規(guī)格說明??蓤?zhí)行代碼會(huì)被自動(dòng)生成,或由虛擬機(jī)直接解釋。大部分UML工具支持第二種方法。22.2前向、逆向和雙向工程在CASE工具的領(lǐng)域中,前向工程是從圖形生成代碼,逆向工程是從代碼生成圖形。而雙向工程是則支持雙向生成。所有UML工具都聲稱支持這些特性,但大部分只能實(shí)現(xiàn)其中部分特性。因?yàn)槎鄶?shù)工具只能完成靜態(tài)模型:可以從代碼生成類圖,但無法生成交互圖,或者可以從類圖生成類的基本定義,但無法從交互圖生成方法體。

第四部分

細(xì)化迭代2:處理稅金和計(jì)價(jià)規(guī)則在細(xì)化迭代2中應(yīng)用更多模式進(jìn)行設(shè)計(jì)第23章引言1.我們已經(jīng)學(xué)習(xí)了什么?

在第一次迭代中我們已經(jīng)學(xué)習(xí)了基本的面向?qū)ο蟮南到y(tǒng)分析方法和對象設(shè)計(jì)技術(shù)。2.第二次迭代中的學(xué)習(xí)重點(diǎn)是什么?進(jìn)一步學(xué)習(xí)對象設(shè)計(jì)技術(shù),并學(xué)習(xí)使用更多的設(shè)計(jì)模式來創(chuàng)建穩(wěn)固的設(shè)計(jì),學(xué)習(xí)應(yīng)用UML使模型可視化。3.在案例開發(fā)的迭代1中我們完成了什么?1)所有的階段性軟件都已充分地測試,包括單元測試、驗(yàn)收測試、負(fù)載測試、可用性測試。

2)客戶定期地參與了對已完成部分的評估。開發(fā)人員已獲得對調(diào)整和澄清需求的反饋,客戶也認(rèn)可了系統(tǒng)進(jìn)一步完善的需求。

3)已經(jīng)對已完成的系統(tǒng)進(jìn)行了完整的集成和固化,使其成為基線化的內(nèi)部版本。4.從迭代1到迭代2的轉(zhuǎn)移過程中有許多事情要做。為突出重點(diǎn),不詳細(xì)討論。這些事情包括:*迭代計(jì)劃會(huì)議*使用UML工具從第一次迭代的源碼中導(dǎo)出圖形,并掛在墻上,作為溝通和新一輪迭代的起點(diǎn)。*對UI的分析和設(shè)計(jì),以及對數(shù)據(jù)庫的建模和實(shí)現(xiàn)也在進(jìn)行中。*舉行了新一輪需求討論會(huì)。5.迭代2的需求和重點(diǎn)在迭代2中我們將忽略需求分析和領(lǐng)域分析,把重點(diǎn)放在對象設(shè)計(jì)和模式應(yīng)用上。在POS應(yīng)用的第二次迭代中,關(guān)注處理銷售用例場景的如下需求:*支持第三方外部服務(wù)的變化,如處理支付和計(jì)算稅金等。*支持復(fù)雜的定價(jià)規(guī)則。*支持窗口刷新。這些需求在初始階段就已在用例和補(bǔ)充規(guī)格說明中提出了。第24章快速地更新分析目標(biāo)快速地突出顯示一些分析制品的變更。1.用例需要更新嗎?就POS應(yīng)用的案例來說,第二次迭代仍然是基于原有用例,因?yàn)樵诘谝淮蔚形覀冎惶幚砹酥鞒晒鼍?,且只處理現(xiàn)金支付。在第二次迭代中要處理稅金計(jì)算和計(jì)價(jià)規(guī)則問題。原有用例已反映這些需求,不必更新。

2.SSD需要更新嗎?

本次迭代要處理對具有不同接口的第三方外部系統(tǒng)(如稅金計(jì)算器)的支持,POS應(yīng)用系統(tǒng)將與這些外部系統(tǒng)進(jìn)行通信。增加邊界外的參與者,系統(tǒng)事件會(huì)發(fā)生變化,一些系統(tǒng)操作的要求也會(huì)變化。所以,SSD必須更新。下圖示出了對原有SSD的更新:

1)參與者的更新

2)系統(tǒng)操作流的更新圖中包括在下一次迭代要處理的信用卡支付需求。描述信用卡支付的SSD場景makeCreditPayment(credNum,expiryDate)reply=requestApproval(request)postReceivable(receivable)?actor?:CreditAuthorizationService?actor?:AccountsenterItem(itemID,quantity):NextGenPOS

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論