五分鐘技術(shù)趣談 | 單元測試的重要性及方案推薦
Part 01 什么是單元測試
單元測試是一種軟件測試方法,用于測試軟件系統(tǒng)的最小可測試單元,例如函數(shù)、方法或類的行為。單元測試通常由開發(fā)人員編寫,并在編寫代碼時就開始執(zhí)行。這樣可以保證實(shí)時檢測代碼中的錯誤、缺陷和潛在的問題,確保代碼滿足預(yù)期的行為和輸出。
單元測試可以分為如下幾個步驟,然后在開發(fā)中就可以不斷地編寫、執(zhí)行、分析測試用例,并修復(fù)問題。
- 確定測試目標(biāo):在編寫單元測試之前,開發(fā)人員需要明確測試目標(biāo)和預(yù)期結(jié)果。這有助于確保測試的準(zhǔn)確性和完整性。
- 編寫測試用例:測試用例是單元測試的核心。測試用例應(yīng)該覆蓋代碼的各種情況和條件,并檢測其行為和輸出。
- 執(zhí)行測試用例:測試用例可以手動執(zhí)行,也可以通過自動化測試框架執(zhí)行。自動化測試框架可以幫助開發(fā)人員更快速和有效地執(zhí)行測試用例,并自動報(bào)告測試結(jié)果。
- 分析測試結(jié)果:分析測試結(jié)果可以幫助開發(fā)人員更好地理解代碼的行為和輸出,發(fā)現(xiàn)問題和改進(jìn)代碼。
- 修復(fù)問題:在發(fā)現(xiàn)問題之后,開發(fā)人員需要及時修復(fù)問題,確保代碼的質(zhì)量和穩(wěn)定性。修復(fù)問題后,需要重新運(yùn)行測試用例,確保問題已經(jīng)解決并且沒有引入新的問題。
Part 02 單元測試的作用
- 確保代碼質(zhì)量:單元測試可以幫助開發(fā)人員檢測代碼中的錯誤、缺陷和潛在的問題。通過及時發(fā)現(xiàn)和修復(fù)這些問題,可以保證代碼的質(zhì)量和穩(wěn)定性。
- 提高代碼可維護(hù)性:單元測試可以幫助開發(fā)人員更好地理解代碼,了解其行為和預(yù)期輸出,這使得代碼更易于維護(hù)和修改。
- 提高開發(fā)效率:通過早期發(fā)現(xiàn)和解決問題,可以減少后期的調(diào)試時間和資源成本,提高開發(fā)效率。
- 促進(jìn)團(tuán)隊(duì)合作:單元測試可以作為開發(fā)團(tuán)隊(duì)的交流和協(xié)作工具。團(tuán)隊(duì)成員可以分享代碼和測試結(jié)果,并共同解決問題。
- 改進(jìn)設(shè)計(jì)和架構(gòu):單元測試可以促進(jìn)更好的設(shè)計(jì)和架構(gòu)實(shí)踐。通過編寫可測試的代碼和測試用例,可以幫助開發(fā)人員更好地理解系統(tǒng)的組成部分,并促進(jìn)設(shè)計(jì)和架構(gòu)的優(yōu)化。
Part 03 Java項(xiàng)目中單元測試方案推薦
- Junit5
JUnit是Java領(lǐng)域內(nèi)最為流行的單元測試框架,Junit測試又稱白盒測試,旨在驗(yàn)證被測試的軟件如何(How)完成功能和完成什么樣(What)的功能。Junit的最新版本Junit 5集合了 Junit Platform、Junit Jupiter、Junit Vintage等。其中,Junit Platform是在JVM上啟動測試框架的基礎(chǔ);Junit Jupiter提供了新的編程模型,包含了一個測試引擎,在Junit Platform上運(yùn)行;Junit Vintage 提供了兼容JUnit4.x,Junit3.x的測試引擎,幫助老項(xiàng)目依賴包的過度升級。Springboot2.2.0+中默認(rèn)集成:
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>1.23</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>1.23</version>
</dependency>
常用注解及說明如下:
@Test :表示方法是測試方法(即框架操作對象),與JUnit4的@Test不同,JUnit5的@Test非常單一不能聲明任何屬性,拓展的測試都由Jupiter提供
@DisplayName :為測試類或者測試方法設(shè)置展示的名稱
@BeforeAll :表示在所有單元測試方法之前執(zhí)行
@AfterAll :表示在所有單元測試方法之后執(zhí)行
@BeforeEach :表示在每個單元測試方法之前執(zhí)行
@AfterEach :表示在每個單元測試方法之后執(zhí)行
@Timeout :表示測試方法運(yùn)行超過指定時間將會拋出TimeoutException異常
@Disabled :表示測試類或測試方法不執(zhí)行,類似于JUnit4中的@Ignore
@RepeatedTest :表示方法需要重復(fù)執(zhí)行的次數(shù)
@ExtendWith :為測試類或測試方法提供@Autowired的IOC注入
- JMH
JMH(Java Microbenchmark Harness)是java領(lǐng)域用于代碼微基準(zhǔn)測試的工具套件,主要是基于方法層面的基準(zhǔn)測試,精度可以達(dá)到納秒級,它是由Java虛擬機(jī)團(tuán)隊(duì)開發(fā)的。當(dāng)你定位到熱點(diǎn)方法,希望進(jìn)一步優(yōu)化方法性能的時候,就可以使用 JMH 對優(yōu)化的結(jié)果進(jìn)行量化的分析
springboot集成方式導(dǎo)入依賴包如下(最新版本1.36):
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>1.23</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>1.23</version>
</dependency>
JMH的應(yīng)用場景如下:
(1)想準(zhǔn)確地知道某個方法需要執(zhí)行多長時間及執(zhí)行時間和輸入之間的相關(guān)性;
(2)對比接口不同實(shí)現(xiàn)在給定條件下的吞吐量;
(3)查看多少百分比的請求在多長時間內(nèi)完成。
上述兩個方案前者是確保代碼運(yùn)行的正確性,后者旨在測試代碼運(yùn)行的性能,在項(xiàng)目實(shí)戰(zhàn)中可以做到強(qiáng)強(qiáng)聯(lián)合,確保代碼質(zhì)量和穩(wěn)定性,幫助完善或改進(jìn)設(shè)計(jì)和架構(gòu),編寫高質(zhì)量的單元測試需要遵循最佳實(shí)踐。
Part 04 總結(jié)
單元測試的目的是為了驗(yàn)證軟件開發(fā)的功能、性能、完整性。當(dāng)軟件發(fā)生變化時,單元測試可以幫助開發(fā)人員確定哪些部分受到影響,以及如何更改代碼。還可以幫助開發(fā)人員了解他們的代碼,從單元測試中獲得反饋,從而更好繼續(xù)開發(fā)軟件。文中提到的基于JUnit5和JMH兩種互補(bǔ)方案,可以從代碼功能和性能兩個角度保證軟件交付成果。
?? 參考文獻(xiàn)
[1] 蔡高亮,2008, 軟件單元測試[J],http://www.its.cesi.cn/qkContent/articleDetail/1043,2023/3/13.