版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、.,1,如何提高產(chǎn)品開發(fā)品質(zhì),.,2,講解內(nèi)容,.,3,一、目前開發(fā)過程存在的問題,沒有完善的品質(zhì)保障流程質(zhì)量低下的代碼不重視測試,.,4,產(chǎn)品開發(fā)流程現(xiàn)狀,開發(fā)人員編寫代碼,調(diào)試,肉眼觀察,有問題,沒問題(自認為),可交付的代碼,編譯,修正編譯錯誤,登記到JIRA上,客戶提出需求或現(xiàn)場發(fā)現(xiàn)bug,.,5,產(chǎn)品品質(zhì)管理嚴重缺失,該流程的最終目標和工作重心都是完成產(chǎn)品功能開發(fā),品質(zhì)管理嚴重缺失。產(chǎn)品的開發(fā)質(zhì)量完全靠開發(fā)人員的個人責(zé)任心以及工作經(jīng)驗來保障,缺乏一個穩(wěn)定可靠的質(zhì)量保障流程。這種流程開發(fā)出來的產(chǎn)品往往是質(zhì)量不可靠,需要經(jīng)常返工的劣質(zhì)產(chǎn)品。,.,6,質(zhì)量低下的代碼是導(dǎo)致產(chǎn)品品質(zhì)不好的根本
2、原因,質(zhì)量低下的代碼體現(xiàn)在以下幾個方面:重復(fù)的代碼過長的函數(shù)過大類過長的參數(shù)列表過度復(fù)雜的邏輯判斷數(shù)據(jù)泥團,.,7,沒有專職測試人員來進行功能性測試工作,在目前的開發(fā)流程中,開發(fā)出來的代碼只經(jīng)過開發(fā)人員自己簡單的測試,沒有專職的測試人員來進行詳細的功能性測試。這樣導(dǎo)致的結(jié)果往往是提交到現(xiàn)場的代碼會帶有不少BUG,一定要經(jīng)過多次返工才能達到較高的品質(zhì)。而且這樣做的另一個后果是把客戶當作測試人員,會給客戶留下產(chǎn)品品質(zhì)不穩(wěn)定這樣一種非常不好的客戶體驗。,.,8,開發(fā)人員在開發(fā)過程中不重視單元測試,單元測試是提高產(chǎn)品品質(zhì)非常重要的一個方法,而我們的開發(fā)人員往往會忽視這一點。如果沒有單元測試,僅僅依靠測
3、試人員的功能性測試,那么這樣的測試工作量會非常大,每次修改一個功能,可能會影響到的其他功能都要一一測試,不僅測試時間會非常長,而且效果也不好,很多細節(jié)不一定每次都能測到,這些都是產(chǎn)生BUG的隱患。同時由于我們業(yè)務(wù)需求都非常復(fù)雜多變的,沒有一個完善自動化測試流程,而僅僅依靠人工測試,對產(chǎn)品品質(zhì)的影響是不言而喻的。,.,9,我們的目標!,編寫出邏輯清晰、結(jié)構(gòu)簡潔、擴展性良好、可測試性高的優(yōu)秀代碼。強化單元測試工作,提高單元測試覆蓋率,搭建自動單元測試集,通過日構(gòu)建來持續(xù)集成,對產(chǎn)品質(zhì)量進行全面控制。通過嚴格的產(chǎn)品質(zhì)量管理流程,強化質(zhì)量管理工作,將所有BUG消滅在公司內(nèi)部。,.,10,二、產(chǎn)品開發(fā)品
4、質(zhì)保障流程,.,11,開發(fā)質(zhì)量管理,本開發(fā)流程的目標是開發(fā)出質(zhì)量優(yōu)良的產(chǎn)品,流程的重心在于質(zhì)量管控,通過質(zhì)量保障人員對產(chǎn)品質(zhì)量進行全面把關(guān)。對于沒有編寫單元測試的代碼直接打回!質(zhì)量保障人員負責(zé)進行功能性測試,并對提交出去的代碼負責(zé)。質(zhì)量保障人員另一個職責(zé)是思考如何持續(xù)改進產(chǎn)品質(zhì)量。,.,12,需求管控,對每個需求進行分級評審,最大程度的降低需求變更的頻度。所有需求開發(fā)前都經(jīng)過內(nèi)部評審,對于一些復(fù)雜需求把握更加準確,不至于在開發(fā)時候產(chǎn)生較大偏差。所有需求的開發(fā)工作都有經(jīng)過客戶簽字的開發(fā)工作量評估,為商務(wù)工作開展創(chuàng)造有利條件。所有需求都有詳細開發(fā)計劃,片區(qū)人員可以安排相應(yīng)的測試計劃。,.,13,全
5、過程管控,所有缺陷和經(jīng)過評審的需求都必須在JIRA上登記,否則不予開發(fā)。開發(fā)計劃通過JIRA進行精確體現(xiàn)。片區(qū)人員可以通過JIRA實時跟蹤產(chǎn)品開發(fā)進度。方便后續(xù)各類工作量的統(tǒng)計。,.,14,三、利用代碼重構(gòu)來提高代碼質(zhì)量,重構(gòu)(Refactoring):是對軟件內(nèi)部結(jié)構(gòu)的一種調(diào)整,目的是在不改變外部行為的前提下,提高其可理解性,降低其修改成本,.,15,為什么重構(gòu)(1),改進軟件的設(shè)計。程序員對代碼所做的為了滿足短期利益代碼改動,或再沒有完全清楚增個架構(gòu)下的改動,都很容易是代碼失去它的清晰結(jié)構(gòu),偏離需求或設(shè)計。而這些改動的積累很容易使代碼偏離它原先設(shè)計的初衷而變得不可立即和無法維護。重構(gòu)則幫助
6、重新組織代碼,重新清晰的體現(xiàn)結(jié)構(gòu)和進一步改進設(shè)計。,.,16,為什么重構(gòu)(2),提高代碼質(zhì)量,更易被理解容易理解的代碼可以很容易的維護和做進一步的開發(fā)。即使對寫這些代碼的程序員本身,容易理解代碼也可以幫助容易地做修改。程序代碼也是文檔。而代碼首先是寫給人看的,讓后才是給計算機看的。重構(gòu)幫助盡早的發(fā)現(xiàn)錯(Bugs)重構(gòu)是一個codereview和反饋的過程。在另一個時段重新審視自己或別人代碼,可以更容易的發(fā)現(xiàn)問題和加深對代碼的理解。重構(gòu)是一個良好的軟件開發(fā)習(xí)慣。,.,17,為什么重構(gòu)(3),重構(gòu)可以提高開發(fā)速度重構(gòu)對設(shè)計和代碼的改進,都可以有效的提高開發(fā)速度。好的設(shè)計和代碼質(zhì)量實體提高開發(fā)速度的
7、關(guān)鍵。在一個有缺陷的設(shè)計和混亂代碼基礎(chǔ)上的開發(fā),即使表面上進度較快,但本質(zhì)是試延后對設(shè)計缺陷的發(fā)現(xiàn)和對錯誤的修改,也就是延后了開發(fā)風(fēng)險,最終要在開發(fā)的后期付出更多的時間和代價。項目的維護成本遠高于開發(fā)成本.,.,18,何時重構(gòu)?,添加或者修改功能時一并重構(gòu)為了增加一個新的功能或者修改原有的功能,程序員需要首先讀懂現(xiàn)有的代碼。修補錯誤時一并重構(gòu)為了修復(fù)一個Bug,程序員需要讀懂現(xiàn)有的代碼。CodeReview時一并重構(gòu),.,19,何時不該重構(gòu)?,代碼太混亂,設(shè)計完全錯誤。與其Refactor,不如重寫。明天是DeadLine永遠不要做Last-Minute-Change。推遲重構(gòu),但不可以忽略,
8、即使進入產(chǎn)品期的代碼都正確的運行。,.,20,重構(gòu)方法介紹:提取函數(shù)(1),Stringname=request.getParameter(Name);if(name!=nullif(age!=nullif(!isNullOrEmpty(name).Stringage=request.getParameter(Age);if(!isNullOrEmpty(age).privatebooleanisNullOrEmpty(finalStringstring)if(string!=null,.,21,重構(gòu)方法介紹:提取函數(shù)(2),提取函數(shù)是我最常用的重構(gòu)手法之一。當我看見一個過長的函數(shù)或者一段需要
9、注釋才能讓人理解用途的代碼,我就會將這段代碼放進一個獨立的函數(shù)中。有數(shù)個原因造成我喜歡簡短而有良好命名的函數(shù)。首先,如果每個函數(shù)的粒度都很小,那么函數(shù)之間彼此復(fù)用的機會就更大;其次,這會使高層函數(shù)讀起來就像一系列注釋;再者,如果函數(shù)都是細粒度,那么函數(shù)的覆寫(override)也會更容易些:的確,如果你習(xí)慣了看大型函數(shù),恐怕需要一段時問才能適應(yīng)達種新風(fēng)格,而且只有當你能給小型函數(shù)很好地命名時,它們才能真正起作用,所以你需要在函數(shù)名稱下點功夫,一個函數(shù)多長才算合適?在我看來.長度不是問題,關(guān)鍵在于函數(shù)名稱和函數(shù)本體之間的語義距離,如果提煉動作可以強化代碼的清晰度,那就去做,就是函數(shù)名稱比提煉出來
10、的代碼還長也無所謂。,.,22,重構(gòu)方法介紹:去除臨時變量(1),.,23,重構(gòu)方法介紹:去除臨時變量(2),我喜歡盡量除去函數(shù)內(nèi)的臨時變量。臨時變量往往形成問題,它們會導(dǎo)致大量參數(shù)被傳來傳去,而其實完全沒有這種必要。你很容易失去它們的蹤跡,尤其在長長的函數(shù)之中更是如此。而且,臨時變量的存在,往往會阻礙提取函數(shù)等其他重構(gòu)手法的進行。,.,24,重構(gòu)方法介紹:重新命名函數(shù)(1),publicStringgetItemName(intitemSort,StringitemName)return+itemSort+、+itemName;,publicStringformatItemName(inti
11、temSort,StringitemName)return+itemSort+、+itemName;,.,25,重構(gòu)方法介紹:重新命名函數(shù)(2),我極力提倡的一種編程風(fēng)格就是:將復(fù)雜的處理過程分解成小函數(shù)。但是,如果做得不好,這會使你費盡周折卻弄不清楚這些小函數(shù)各白的用途、.要避免這種麻煩,關(guān)鍵就在于給函數(shù)起一個好名稱;函數(shù)的名稱應(yīng)該準確表達它的用途;給函數(shù)命名有一個好辦法。首先考慮應(yīng)該給這個函數(shù)寫上一句怎樣的注釋,然后想辦法將注釋變成函數(shù)名稱。人生不如意十之八九:你常常無法第一次就給函數(shù)起一個好名稱,這時候你可能會想,就這樣將就著吧,畢竟只是一個名稱而已。當心!這是惡魔的召喚,是通向混亂之路
12、,千萬不要被它誘惑!如果你看到一個函數(shù)名稱不能很好地表達它的用途,應(yīng)該馬上加以修改。記住,你的代碼首先是為人寫的,其次才是為計算器寫的。而人需要良好名稱的函數(shù)。想想過去曾經(jīng)浪費的無數(shù)時間吧,如果給每個函數(shù)都起一個良好的名稱,也許你可以節(jié)約好多時間。取一個好名稱并不容易,需要經(jīng)驗,要想成為一個真正的編程高手,取名稱的水平是至關(guān)重要的。,.,26,重構(gòu)方法介紹:以多態(tài)取代條件表達式(1),publicclassPlanUtilpublicvoidsetPlanState(intplanYear,intitemId,intdataType)switchdataTypecase1:setPrePlan
13、State(planYear,itemId);case2:setColPlanState(planYear,itemId);case3:setAftPlanState(planYear,itemId);default:thrownewRuntimeException(不正確的計劃類型:+dataType);/.更新建議計劃狀態(tài)publicvoidsetPrePlanState/.更新綜合計劃狀態(tài)publicvoidsetColPlanState./.更新開工計劃狀態(tài)publicvoidsetAftPlanState.,publicclassPlanUtilpublicstaticPlanUti
14、lcreate(intdataType)switch(dataType)case1:returnnewPrePlanUtil();case2:returnnewColPlanUtil();case3:returnnewAftPlanUtil();default:thrownewRuntimeException(不正確的計劃類型:+dataType);publicabstractvoidsetPlanState(intplanYear,intitemId,intdataType);publicabstractvoidsavePlan(intplanYear,intitemId,intdataTy
15、pe);,.,27,重構(gòu)方法介紹:以多態(tài)取代條件表達式(2),/保存計劃數(shù)據(jù)publicvoidsavePlan(intplanYear,intitemId,intdataType)switchdataTypecase1:savePrePlan(planYear,itemId);case2:saveColPlan(planYear,itemId);case3:saveAftPlan(planYear,itemId);default:thrownewRuntimeException(不正確的計劃類型:+dataType);/.保存建議計劃數(shù)據(jù)publicvoidsavePrePlan/.保存綜合
16、計劃數(shù)據(jù)publicvoidsaveColPlan/.保存開工計劃數(shù)據(jù)publicvoidsaveAftPlan,publicclassPrePlanUtilextendsPlanUtilpublicvoidsetPlanState(intplanYear,intitemId,intdataType).更新建議計劃狀態(tài)方法publicvoidsavePlan(intplanYear,intitemId,intdataType)保存建議計劃數(shù)據(jù)方法publicclassColPlanUtilextendsPlanUtilpublicvoidsetPlanState(intplanYear,int
17、itemId,intdataType).更新綜合計劃狀態(tài)方法publicvoidsavePlan(intplanYear,intitemId,intdataType)保存綜合計劃數(shù)據(jù)方法,.,28,重構(gòu)方法介紹:以多態(tài)取代條件表達式(3),/調(diào)用更新計劃狀態(tài)的方法planUtil.setPlanState(year,itemId,dataType);/調(diào)用保存計劃數(shù)據(jù)的方法planUtil.savePlanyear,itemId,dataType);,publicclassAftPlanUtilextendsPlanUtilpublicvoidsetPlanState(intplanYear,
18、intitemId,intdataType).更新開工計劃狀態(tài)方法publicvoidsavePlan(intplanYear,intitemId,intdataType)保存開工計劃數(shù)據(jù)方法/調(diào)用PlanUtilplanUtil=PlanUtil.create(dataType);/調(diào)用更新計劃狀態(tài)的方法planUtil.setPlanState(year,itemId,dataType);/調(diào)用保存計劃數(shù)據(jù)的方法planUtil.savePlan(year,itemId,dataType);,.,29,重構(gòu)方法介紹:以多態(tài)取代條件表達式(4),多態(tài)最根本的好處就是:如果你需要根據(jù)對象的不同
19、型別而采取不同的行為,多態(tài)使你不必編寫明顯的條件式。正因為有了多態(tài),所以你會發(fā)現(xiàn):針對typecode(型別碼)而寫的switch語句,以及針對typestring(型別名稱字符串)而寫的if-then-else語句在面向?qū)ο蟪绦蛑泻苌俪霈F(xiàn)。多態(tài)能夠給你帶來很多好處。如果同一組條件式在程序許多地點出現(xiàn),那么使用多態(tài)的收益是最大的。使用條件式時,如果你想添加一種新型別,就必須杳找并更新所有條件式。但如果改用多態(tài),只需建一個新的subclass并在其中提供適當?shù)暮瘮?shù)就行了。class用戶不需要了解這個subclass,這就大大降低了系統(tǒng)各部分之間的耦合程度,使系統(tǒng)升級.更加容易。,.,30,重構(gòu)方
20、法介紹:以委托取代繼承(1),/繼承解決方案publicclassBusPlanManagerServiceImplpublicvoidsetPlanState(intplanYear,intitemId,intdataType).更新建議計劃狀態(tài)方法publicvoidsavePlan(intplanYear,intitemId,intdataType)保存建議計劃數(shù)據(jù)方法publicclassPrePlanServiceextendsBusPlanManagerServiceImpl.publicclassColPlanServiceextendsBusPlanManagerService
21、Impl.publicclassAftPlanServiceextendsBusPlanManagerServiceImpl.,/委托解決方案publicclassBusPlanManagerServiceImplpublicvoidsetPlanState(intplanYear,intitemId,intdataType)PlanUtilplanUtil=PlanUtil.create(dataType);/調(diào)用更新計劃狀態(tài)的方法planUtil.setPlanState(year,itemId,dataType);publicvoidsavePlan(intplanYear,intite
22、mId,intdataType)PlanUtilplanUtil=PlanUtil.create(dataType);/調(diào)用更新計劃狀態(tài)的方法planUtil.savePlan(year,itemId,dataType);,.,31,重構(gòu)方法介紹:以委托取代繼承(2),繼承是一件很棒的事,但有時候它并不是你要的。常常你會遇到這樣的情況:一開始你繼承了一個class,隨后發(fā)現(xiàn)superclass中的許多操作井不真正適用于subclass。這種情況下你所擁有的接口并末真正反映出class的功能。或者,你可能發(fā)現(xiàn)你從superclass中繼承了一大堆subclas并不需要的數(shù)據(jù),抑或者你可能發(fā)現(xiàn)su
23、perclass中的某些protected函數(shù)對subclass并沒有什么意義。你可以選擇容忍,并接受傳統(tǒng)說法:subclass可以只使用superclas、功能的一部分。但這樣做的結(jié)果是:代碼傳達的信息與你的意圖南轅北轍,這是一種混淆,你應(yīng)該將它去除。如果以委托取代繼承,你可以更清楚地表明:你只需要受托類的一部分功能。接口中的哪一部分應(yīng)該被使用,哪一部分應(yīng)該被忽略,完全由你主導(dǎo)控制。這樣做的成本則是需耍額外寫出委托函數(shù),但這些函數(shù)都非常簡單,極少可能出錯。,.,32,重構(gòu)方法介紹:引入?yún)?shù)對象(1),publicListgetYearPlanList(StringoperatorID,Str
24、ingplanYear,StringiSeason,StringplanType,StringdataType).publicListgetLastYearPlanList(StringoperatorID,StringplanYear,StringiSeason,StringplanType,StringdataType)publicvoidfillPlanData(StringoperatorID,StringplanYear,StringiSeason,StringplanType,StringdataType)PlanDataplanData=newPlanData();planDat
25、a.setYeraPlanList(getYearPlanList(operatorID,planYear,iSeason,planType,dataType);planData.setLastYeraPlanList(getLastYearPlanList(operatorID,planYear,iSeason,planType,dataType);,publicclassPlanParamObjprivateStringoperatorID;privateStringplanYear;privateStringiSeason;privateStringplanType,;privateSt
26、ringdataType;publicPlanParamObj(StringoperatorID,StringplanYear,StringiSeason,StringplanType,StringdataType)this.operatorID=operatorID;this.planYear=planYear;this.iSeason=iSeason;this.planType=planType;this.dataType=dataType;,.,33,重構(gòu)方法介紹:引入?yún)?shù)對象(2),publicListgetYearPlanList(PlanParamObjparamObj).publ
27、icListgetLastYearPlanList(PlanParamObjparamObj).publicvoidfillPlanData(StringoperatorID,StringplanYear,StringiSeason,StringplanType,StringdataType)PlanParamObjparamObj=newPlanParamObj(operatorID,planYear,iSeason,planType,dataType);PlanDataplanData=newPlanData();planData.setYeraPlanList(getYearPlanLi
28、st(paramObj);planData.setLastYeraPlanList(getLastYearPlanList(paramObj);,.,34,重構(gòu)方法介紹:引入?yún)?shù)對象(3),你常會看到特定的數(shù)組參數(shù)總是一起被傳遞。可能有好幾個函數(shù)都使用這一組參數(shù),這些函數(shù)可能隸屬同個class,也可能隸屬不同的classes。這樣一組參數(shù)就是所謂的dataClump(數(shù)據(jù)泥團),我們可以運用一個對象包裝所有這些數(shù)據(jù),再以該對象取代它們。哪伯只是為了把這些數(shù)據(jù)組織在一起,這樣做也是值得的。本項重構(gòu)的價值在于縮短了參數(shù)列的長度,而你知道,過長的參數(shù)列總是難以理解的。此外,新對象所定義的訪問函數(shù)還可
29、以使代碼更具一致性,這又進一步降低了代碼的理解難度和修改難度。本項重構(gòu)還可以帶給你更多好處。當你把這些參數(shù)組織到起之后,往往很快可以發(fā)現(xiàn)一些可被移至新建class的行為。通常,原本使用那些參數(shù)的函數(shù)對那些參數(shù)會有一些共通措施,如果將這些共通行為移到新對象中,你可以減少很多重復(fù)代碼,.,35,重構(gòu)方法介紹:函數(shù)遷移(1),publicclassRepUtilFuncprivateListinitFundList().this.copyFundView(fView,planView);/匯總投資計劃數(shù)據(jù)privatevoidcopyFundView(FundViewfView,PlanViewpl
30、anView)fView.setFund(fView.getFund()+planView.getFund();fView.setUpprefund(fView.getUpprefund()+planView.getUpprefund();fView.setDownprefund(fView.getDownprefund()+planView.getDownprefund();,publicclassRepUtilFuncprivateListinitFundList().fView.copyFundView(planView);/匯總投資計劃數(shù)據(jù),.,36,重構(gòu)方法介紹:函數(shù)遷移(2),pu
31、blicclassFundViewprivatedoublefund;privateStringupprefund;privateStringdownprefund;getset方法,publicclassFundViewprivatedoublefund;privateStringupprefund;privateStringdownprefund;getset方法publicvoidcopyFundView(PlanViewplanView)this.setFund(this.getFund()+planView.getFund();this.setUpprefund(this.getUp
32、prefund()+planView.getUpprefund();this.setDownprefund(this.getDownprefund()+planView.getDownprefund();,.,37,重構(gòu)方法介紹:函數(shù)遷移(3),函數(shù)遷移是重構(gòu)理論的支柱。如果一個class有太多行為,或如果一個class與另一個class有太多合作而形成高度耦合,我就會遷移函數(shù)。通過這種手段,我可以使系統(tǒng)中的classes更簡單,這些classes最終也將更干凈利落地實現(xiàn)系統(tǒng)交付的任務(wù)。常常我會瀏覽class的所有函數(shù),從中尋找這樣的函數(shù),使用另一個對象的次數(shù)比使用自己所駐對象的次數(shù)還多,就會
33、進行函數(shù)遷移。,.,38,重構(gòu)方法介紹:將過程化設(shè)計轉(zhuǎn)換為面向?qū)ο笤O(shè)計,有時間的話用一個實際例子進行展示。,.,39,四、測試驅(qū)動開發(fā)方法簡介,測試驅(qū)動開發(fā)(TestDrivenDevelopment,英文縮寫TDD)是極限編程的一個重要組成部分,它的基本思想就是在開發(fā)功能代碼之前,先編寫代碼的單元測試用例。也就是說在明確要開發(fā)某個功能后,首先思考如何對這個功能進行測試,并完成測試用例的編寫,然后編寫相關(guān)的代碼滿足這些測試用例。循環(huán)進行添加其他功能,直到完成全部功能的開發(fā)。代碼整潔可用(cleancodethatworks)是測試驅(qū)動開發(fā)所追求的目標。,.,40,測試驅(qū)動開發(fā)優(yōu)點(1),需求向
34、來就是軟件開發(fā)過程中感覺最不好明確描述、易變的東西。這里說的需求不只是指用戶的需求,還包括對代碼的使用需求。很多開發(fā)人員最害怕的就是后期還要修改某個類或者函數(shù)的接口進行修改或者擴展,為什么會發(fā)生這樣的事情就是因為這部分代碼的使用需求沒有很好的描述。測試驅(qū)動開發(fā)就是通過編寫測試用例,先考慮代碼的使用需求(包括功能、過程、接口等),而且這個描述是無二義的,可執(zhí)行驗證的。通過編寫這部分代碼的測試用例,對其功能的分解、使用過程、接口都進行了設(shè)計。而且這種從使用角度對代碼的設(shè)計通常更符合后期開發(fā)的需求??蓽y試的要求,對代碼的內(nèi)聚性的提高和復(fù)用都非常有益。因此測試驅(qū)動開發(fā)也是一種代碼設(shè)計的過程。開發(fā)人員通
35、常對編寫文檔非常厭煩,但要使用、理解別人的代碼時通常又希望能有文檔進行指導(dǎo)。而測試驅(qū)動開發(fā)過程中產(chǎn)生的測試用例代碼就是對代碼的最好的解釋。,.,41,測試驅(qū)動開發(fā)優(yōu)點(2),快樂工作的基礎(chǔ)就是對自己有信心,對自己的工作成果有信心。當前很多開發(fā)人員卻經(jīng)常在擔(dān)心:“代碼是否正確?”“辛苦編寫的代碼還有沒有嚴重bug?”“修改的新代碼對其他部分有沒有影響?”。這種擔(dān)心甚至導(dǎo)致某些代碼應(yīng)該修改卻不敢修改的地步。測試驅(qū)動開發(fā)提供的測試集就可以作為你信心的來源。當然測試驅(qū)動開發(fā)最重要的功能還在于保障代碼的正確性,能夠迅速發(fā)現(xiàn)、定位bug。而迅速發(fā)現(xiàn)、定位bug是很多開發(fā)人員的夢想。針對關(guān)鍵代碼的測試集,以
36、及不斷完善的測試用例,為迅速發(fā)現(xiàn)、定位bug提供了條件。我的一段功能非常復(fù)雜的代碼使用TDD開發(fā)完成,真實環(huán)境應(yīng)用中只發(fā)現(xiàn)幾個bug,而且很快被定位解決。您在應(yīng)用后,也一定會為那種自信的開發(fā)過程,功能不斷增加、完善的感覺,迅速發(fā)現(xiàn)、定位bug的能力所感染,喜歡這個技術(shù)的。,.,42,測試驅(qū)動開發(fā)基本過程,明確當前要完成的功能。可以記錄成一個TODO列表??焖偻瓿舍槍Υ斯δ艿臏y試用例編寫。測試代碼編譯不通過。編寫對應(yīng)的功能代碼。測試通過。對代碼進行重構(gòu),并保證測試通過。循環(huán)完成所有功能的開發(fā),.,43,測試驅(qū)動開發(fā)案例(1),需求:實現(xiàn)Fibonacci數(shù)列Fibonacci數(shù)列簡介:Fibonacci數(shù)列從第0項開始依次為0,1,1,2,3,5,8的數(shù)列,它存在如下特點:第0,1個數(shù)為0,1。從第2個數(shù)開始,該數(shù)是前面兩個數(shù)之和。,.,44,測試驅(qū)動開發(fā)案例(2),先編寫測試代碼:importjunit.framework.TestCase;publicclassFibonacciTestextendsTestCasepublicvoidtestFibonacci()FibUtilfb=newFibUtil();編寫完測試代碼之后在Eclipse中運行該測試類,發(fā)現(xiàn)Junit運行出錯(顯示了一條紅色杠)這
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 成都一診考試試題及答案
- 神經(jīng)外科主治試題及答案
- 零食小作坊衛(wèi)生管理制度
- 衛(wèi)生罰款制度
- 甜品店衛(wèi)生規(guī)則制度
- 肝膽術(shù)后黃疸的液體治療策略優(yōu)化
- 基督教衛(wèi)生管理制度
- 前廳衛(wèi)生管理制度
- 衛(wèi)生間門前三包制度規(guī)定
- 衛(wèi)生部安全輸血制度
- 2026年及未來5年市場數(shù)據(jù)中國集裝箱物流行業(yè)市場發(fā)展數(shù)據(jù)監(jiān)測及投資戰(zhàn)略規(guī)劃報告
- 中小學(xué)人工智能教育三年發(fā)展規(guī)劃(2026-2028)7500字完整方案目標務(wù)實真能落地
- 七年級地理下冊(人教版)東半球其他的國家和地區(qū)-歐洲西部自然環(huán)境教學(xué)設(shè)計
- 口腔現(xiàn)場義診培訓(xùn)
- 學(xué)校中層管理崗位職責(zé)及分工明細(2026年版)
- 江蘇省南京市六校聯(lián)合體2026屆高一數(shù)學(xué)第一學(xué)期期末監(jiān)測試題含解析
- 就業(yè)部門內(nèi)控制度
- 2026屆江蘇省徐州市侯集高級中學(xué)高一上數(shù)學(xué)期末復(fù)習(xí)檢測試題含解析
- 2026中國電信四川公司校園招聘備考題庫附答案
- 住院患者安全告知
- 2025年山東省濟南市中考地理試題(含答案)
評論
0/150
提交評論