单元测试 代码里面都绝对路径怎么处理_原创 | 编写单元测试和实践TDD (六)测试哪些内容:Right-BICEP...
上一章通過(guò)實(shí)例講了“第一個(gè)單元測(cè)試”到底應(yīng)該怎么做,這一章我們講講“對(duì)一個(gè)工作單元需要測(cè)試它哪些方面的內(nèi)容”?
有6個(gè)值得測(cè)試的部位,統(tǒng)稱(chēng)為:Right-BICEP:
- Right——結(jié)果是否正確?
- B——是否所有的邊界條件都是正確的?
- I——能查一下反向關(guān)聯(lián)嗎?
- C——能用其他手段交叉檢查一下結(jié)果嗎?
- E——你是否可以強(qiáng)制錯(cuò)誤條件發(fā)生?
- P——是否滿(mǎn)足性能要求?
1. 結(jié)果是否正確
例如對(duì)于上一節(jié)的取款案例:原有余額10000元,取款2000后,余額應(yīng)該剩下8000元。我們就要測(cè)試這個(gè)結(jié)果:
assertThat(account.getBalance()).isEqualTo(8000);斷言失敗就表明實(shí)現(xiàn)代碼有錯(cuò),需要修改后重新測(cè)試。
2. 邊界條件
代碼中的bug往往都出現(xiàn)在“邊界條件”附近,也就是說(shuō),在那些條件下,代碼的行為可能不同于平常的、每天都能運(yùn)行到的程序路徑。例如:
- 我們期待接受一個(gè)代表文件路徑的字符串,但客戶(hù)代碼可能傳入一個(gè)包含回車(chē)或冒號(hào)的字符串。
- 我們期待接受一個(gè)代表email的字符串,但客戶(hù)代碼可能傳入一個(gè)沒(méi)有包含“@”的字符串。
- 我們期待接受一個(gè)正數(shù),但客戶(hù)代碼可能傳入0或負(fù)數(shù)。
- 我們期待傳入一個(gè)對(duì)象,但客戶(hù)代碼可能傳入null。
- 我們要從傳入的集合中選擇第一個(gè)元素,但客戶(hù)代碼傳入了一個(gè)空集合。
如果你是一個(gè)橋梁工程師,大橋建好之后,你不能只是在風(fēng)和日麗的日子里,讓一輛車(chē)緩緩駛過(guò)橋面,就宣布大橋經(jīng)過(guò)了充分測(cè)試。作為工作單元的實(shí)現(xiàn)者,我們的代碼交付后,代碼的用戶(hù)可能會(huì)用各種奇葩的方式調(diào)用我們的代碼,我們必須預(yù)先針對(duì)這種種可能情況預(yù)先設(shè)計(jì)應(yīng)對(duì)策略,并通過(guò)單元測(cè)試來(lái)確保工作單元在各種邊界條件下都會(huì)按照我們的預(yù)設(shè)策略那樣執(zhí)行。
一個(gè)想到可能的邊界條件的簡(jiǎn)單辦法就是記住助記詞CORRECT。下一節(jié)我們將詳細(xì)論述CORRECT邊界條件。
3. 檢查反向關(guān)聯(lián)
例如我們要檢查求平方根的函數(shù)squareRoot()的正確性,就可以通過(guò)檢查平方根的平方是否等于當(dāng)初的參數(shù)的當(dāng)時(shí)來(lái)檢查代碼實(shí)現(xiàn)的正確性:
@Testvoid testSquareRootUsingInverse() {double a = 8;double result = squareRoot(a);assertThat(result * result).isCloseTo(a, Percentage.withPercentage(0.00001));}上面的測(cè)試代碼用于測(cè)試squareRoot(double a)函數(shù)的正確性。a的平方根的平方應(yīng)該等于a。
說(shuō)明:在計(jì)算機(jī)中浮點(diǎn)數(shù)無(wú)法精確比較其相等性,因此,兩個(gè)數(shù)只要足夠接近,就可以認(rèn)為相等。在上面的測(cè)試?yán)又?#xff0c;我們把足夠接近定義為相差不超過(guò)0.00001%。
4. 使用其他手段來(lái)實(shí)現(xiàn)交叉檢查
通常而言,實(shí)現(xiàn)一個(gè)工作單元有一種以上的算法。我們選用其中一種最好的來(lái)作為我們的代碼實(shí)現(xiàn),但可以使用其余的算法來(lái)作為單元測(cè)試。當(dāng)兩者的計(jì)算結(jié)果都相同時(shí),我們就可以認(rèn)為我們的代碼實(shí)現(xiàn)是正確的。當(dāng)然前提是兩種算法不會(huì)都是錯(cuò)誤的,但恰好都產(chǎn)生相同的結(jié)果。
例如JDK標(biāo)準(zhǔn)庫(kù)中已經(jīng)有Math.sqrt()這樣的一個(gè)平方根函數(shù)。當(dāng)我們的平方根函數(shù)和標(biāo)準(zhǔn)庫(kù)中的平方根函數(shù)得出的結(jié)果相同時(shí),就可以認(rèn)為我們的的平方根函數(shù)是正確的。
@Testvoid testSquareRootUsingStd() {double a = 8;assertThat(squareRoot(a)).isCloseTo(Math.sqrt(a), Percentage.withPercentage(0.00001));}5. 強(qiáng)制產(chǎn)生錯(cuò)誤條件
在真實(shí)世界中,錯(cuò)誤總會(huì)發(fā)生:磁盤(pán)會(huì)滿(mǎn),WIFI會(huì)斷開(kāi),程序會(huì)崩潰。你應(yīng)該能夠通過(guò)主動(dòng)強(qiáng)制引發(fā)這些錯(cuò)誤,來(lái)測(cè)試你的代碼在這樣極端狀態(tài)下是如何應(yīng)對(duì)這些真實(shí)世界中的問(wèn)題的。
這就是使用Mockito這樣的測(cè)試替身庫(kù)的作用之一——它們能夠模擬各種各樣的異常條件,而不需要無(wú)限期地消極等待真實(shí)世界中異常狀態(tài)的出現(xiàn)。
6. 性能特性
一般的性能測(cè)試是黑盒測(cè)試,采用JMeter這樣的專(zhuān)門(mén)的性能測(cè)試工具進(jìn)行測(cè)試。但是對(duì)于我們所寫(xiě)的代碼,如果里面包含了復(fù)雜的循環(huán),或者處理了大量的數(shù)據(jù),那就應(yīng)該在單元測(cè)試層面測(cè)試一下性能。
通常會(huì)有性能問(wèn)題的測(cè)試都會(huì)耗時(shí)較長(zhǎng)。我們不希望被這些測(cè)試拖慢進(jìn)度。這時(shí)可以采用JUnit的測(cè)試分組策略,將這些耗時(shí)的測(cè)試分到另外的組,只在某些階段執(zhí)行一下測(cè)試。而其他的單元測(cè)試會(huì)經(jīng)常運(yùn)行。
這一章我們講到這里,下一章將講講“CORRECT邊界條件”!
- THE END -
原創(chuàng)作者 | 楊宇Yangyu
編程道與術(shù)原創(chuàng)內(nèi)容
轉(zhuǎn)載請(qǐng)注明“編程道與術(shù)”出處
總結(jié)
以上是生活随笔為你收集整理的单元测试 代码里面都绝对路径怎么处理_原创 | 编写单元测试和实践TDD (六)测试哪些内容:Right-BICEP...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 2023 款特斯拉 Model 3 汽车
- 下一篇: 绑定dictionary 给定关键字不再