TDD in .NET Core - 简介
本文很多內(nèi)容來自選自TDD實例一書。
預(yù)備知識
最好有一些預(yù)備知識,例如xUnit,Moq,如何編寫易于測試的代碼,這些內(nèi)容我都寫了文章:https://www.cnblogs.com/cgzl/p/9178672.html#test。
?
Test Driven Development
什么是TDD(Test Driven Development)?
TDD是一個軟件開發(fā)過程,這個過程依賴于重復(fù)性的小開發(fā)周期:需求被轉(zhuǎn)化為具體的測試用例,然后改進(jìn)程序以便通過測試。
?
在TDD里有兩條規(guī)則:
- 只在有未通過的自動化測試的情況下,你才會去寫新的代碼
- 消滅重復(fù)
?
這兩條規(guī)則在技術(shù)上的含義是:
- 你必須進(jìn)行良好的設(shè)計,運行的代碼可在決策之間提供反饋
- 開發(fā)人員得寫自己的測試
- 開發(fā)環(huán)境可以針對微小的變化需要提供快速的響應(yīng)
- 您的設(shè)計必須由眾多高內(nèi)聚、低耦合的組件組成,這樣測試會更簡單。
?
這兩條規(guī)則也意味著編程的三個任務(wù):
Red,Green,Refactor,這就是TDD的咒語。
?
如果TDD可以很好的執(zhí)行,那么它就會大幅度減少代碼缺陷的密度,也使工作的主題對于相關(guān)人員來說更加清晰。所以,TDD也具有社會含義:
- 如果缺陷密度可以降低到足夠的程度,那么QA就會從被動變?yōu)橹鲃拥墓ぷ鳌?/li>
- 如果那些“讓人討厭的驚喜”可以減少到足夠的程度,那么項目經(jīng)理就可以精確的評估以便讓客戶參與到每日的開發(fā)工作中。
- 如果技術(shù)會議的主題足夠清晰,那么程序員就會按分鐘去工作而不是按天或周來安排和進(jìn)行工作。
- 如果缺陷密度可以降低到足夠的程度,那么我們每天都可以交付出具有新功能的軟件,這就會與客戶建立新的業(yè)務(wù)關(guān)系。
?
這些概念都很簡單,但是動機是什么?為什么開發(fā)人員要去寫自動測試代碼?為什么開發(fā)人員在他們的思維能夠大幅飆升的設(shè)計時,卻只進(jìn)行小步工作? 勇氣。
?
勇氣
TDD是編程過程中管理恐懼的一種辦法。
這個恐懼不是壞事,它是一種合理的恐懼,例如:”這個問題確實很難,我從開始的感覺看不到盡頭“。
如果疼痛是喊停的自然表達(dá),那么恐懼就是告訴你要“小心”。
?
小心是很好的,但是恐懼還有一些其它的影響:
- 讓你不得不進(jìn)行更多試探性操作
- 讓你交流的更少
- 讓你羞于反饋
- 讓你脾氣暴躁
這些影響在開發(fā)的時候?qū)δ愣紱]有任何幫助,尤其是遇到困難問題的時候。那么你如何面對困難處境并且:
- 取代嘗試/試探,而是盡快進(jìn)行具體學(xué)習(xí)
- 取代爭吵,而是進(jìn)行更清楚的溝通
- 取代避免反饋,而是尋求幫助,和具體的反饋
- 控制你自己的脾氣
TDD會管理這些事情。
?
為什么要TDD
從業(yè)務(wù)角度:
- 提供了需求的確認(rèn)。通過編寫測試以及RGR周期,需求確認(rèn)很自然的在軟件開發(fā)的過程中就完成了。
- 捕獲回歸問題。回歸問題就是指隨著軟件新功能的發(fā)布,以前的某些功能卻不好用了。TDD可以很早的發(fā)現(xiàn)回歸問題。
- 綜上兩點,TDD也降低了維護(hù)成本。
?
從開發(fā)人員角度講,TDD還有以下好處:
- 設(shè)計為先的心態(tài)。寫測試的時候,我們就得考慮與軟件的交互應(yīng)該如何實現(xiàn),以便把這些功能需求編程可能。
- 防止過度工程。關(guān)注于如何讓測試通過和滿足客戶的期待,就會讓我們保持正軌,而不是迷失于架構(gòu)設(shè)計和幻想那么無法提供很多價值的最佳抽像設(shè)計中。
- 增加開發(fā)人員的動力。取代了花費幾天時間想盡辦法來實現(xiàn)某個功能這樣的操作,TDD把需求分解成一些測試,并結(jié)合RGR流程,這就允許你可以持續(xù)快速的進(jìn)展并建立成功循環(huán)。
- 收獲自信。通過大量的測試結(jié)果,你感動支配的力量,無論修改、重構(gòu)、增加功能都變得很簡單。
?
第一個實例
在本例中,您將會看到TDD的如下步驟:
?
建立.NET Core 項目
這個很簡單,首先建立一個Console App:
?
然后再添加一個xUnit項目:
?
這個測試項目需要引用Console項目。
?
需求
有這樣一份報表:
?
現(xiàn)在想要做成支持多幣種的:
?
這里還提供了匯率:
?
目標(biāo)就是產(chǎn)生第二張圖那樣的報表。
?
開始操作
我們需要做哪些工作?
- 讓兩種幣種的錢數(shù)可以進(jìn)行加法操作,并通過給定的匯率算出結(jié)果。
- 讓股票單價可以乘以股票數(shù)并得出總額。
上面是一個待辦問題列表(To-Do List)。我們就關(guān)注于這個待辦列表即可。
列表里的問題應(yīng)該是逐個解決的,解決完一個劃掉一個;如果有新問題,就在后邊加上一條。
?
編寫測試
下面我們開始,先不建立對象,先寫測試:
?讓編譯通過
這里有很多問題,編譯也無法通過,這些問題我們也是一個一個來解決。
1. 首先,沒有Dollar這個類,那就建立Dollar這個類:
第一個問題解決了。
?
2. 沒有相應(yīng)的構(gòu)造函數(shù),那就建立構(gòu)造函數(shù):
又解決了一個問題!
?
3. 沒有Times()這個方法,那就建立該方法:
又解決了一個問題!
?
4. 沒有Amount屬性,建立該屬性:
編譯問題都解決了!!
?
看一下測試方法:
編譯錯誤肯定是沒有了。
?
測試Fail
然后跑測試:
不出意料肯定會Fail。
?
讓測試通過
現(xiàn)在有了具體的這個Fail的測試,我們現(xiàn)在的任務(wù)就是讓該測試變成Pass,而不是實現(xiàn)多幣種報表,先讓這個測試通過,再慢慢讓其它測試通過。
您可能不喜歡這樣,但是現(xiàn)在的目標(biāo)不是做出完美的解決方案,目標(biāo)就是讓這個測試通過,所以這時候代碼可能很爛:
我寫死了數(shù)字10。
然后再跑測試:
測試Pass了!!
?
重構(gòu),移除重復(fù)
別著急,周期還沒結(jié)束。
現(xiàn)在,我們需要移除重復(fù)。但是重復(fù)在哪?
通常你看到的重復(fù)是指代碼的重復(fù),這里是指測試中的數(shù)據(jù)和代碼中數(shù)據(jù)的重復(fù)。
這個10是哪來的? 它實際上是:
是通過5乘以2得來的。
所以代碼中的5*2和測試中的5*2是重復(fù)的。 我們需要移除這個重復(fù),但是可能需要不止一步來實現(xiàn)。
?
先把乘法移動到Times方法里試試:
這樣的話,測試仍然會pass:
這是一小步。
?
那么5是哪里來的?
應(yīng)該是從構(gòu)造函數(shù)傳遞進(jìn)來的,我們可以把它存到Amount屬性里:
所以我們可以在Times方法里使用它:
?
現(xiàn)在處理這個2,它應(yīng)該可以使用參數(shù)multiplier代替:
OK!
?
此外,我們可以對代碼的語法進(jìn)行一些優(yōu)化:
其實某些優(yōu)化也應(yīng)該通過TDD的RGR周期來實現(xiàn)。
?
第一篇文章就簡單介紹這些。
?
轉(zhuǎn)載于:https://www.cnblogs.com/cgzl/p/9655053.html
總結(jié)
以上是生活随笔為你收集整理的TDD in .NET Core - 简介的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python中sorted和.sorte
- 下一篇: linux mariadb