20分鐘理清Maven構建中的測試相關工具的關係
如果你用Maven進行系統構建,同時還要同步編寫測試用例,獲取用例成功與否以及用例覆蓋率的相關報告,那麼這些工具你肯定接觸過不少:
- JUnit
- TestNG
- maven-surefire-plugin
- maven-surefire-report-plugin
- emma-maven-plugin
- jacoco-maven-plugin
- cobertura-maven-plugin
- maven-project-info-reports-plugin
- maven-site-plugin
是不是已經有些頭暈了?沒關係,我之前擔任過很長時間的CI構建系統維護者,同時還是這裡面幾個Maven外掛的Maintainer,我將盡最大努力幫你在最短的時間裡理清他們的關係,幫助大家在實際專案中充分發揮這些工具的作用,提升產品質量。首先我們先大體分幾個類別,讓大家有個大概的印象。
- JUnit/TestNG是單元測試工具,可以幫你更方便的編寫測試用例。
- maven-surefire-plugin是一個Maven外掛,幫你在通過Maven構建專案的時候自動執行之前編寫的測試用例。它的輸出檔案是txt或者xml格式的測試報告。
- maven-surefire-report-plugin是一個Maven外掛,幫你將maven-surefire-plugin生成的測試報告轉換為html格式,方便檢視。
- emma-maven-plugin/jacoco-maven-plugin/cobertura-maven-plugin這些是幫助生成測試覆蓋率報告的Maven外掛,他們的輸出檔案也是html格式。
- maven-project-info-reports-plugin是一個Maven外掛,他可以把maven-surefire-report-plugin/emma-maven-plugin/jacoco-maven-plugin/cobertura-maven-plugin這些外掛生成的html格式檔案進行彙總,幫助大家以更好的方式呈現。
- maven-site-plugin是一個Maven外掛,幫你自動生成、部署、啟動你的站點,站點裡面可以有很多東西,其中最重要的部分就是你使用maven-project-info-reports-plugin生成的專案報告。
接下來我們根據之前的分類詳細瞭解下他們:
JUnit/TestNG
- JUnit: http://junit.org/
- TestNG: https://testng.org/
JUnit是老牌單元測試工具了,從3.X,4.X到最新的5.X版本,一直有廣泛的群眾基礎。TestNG和JUnit一樣,也是為了方便編寫單元測試用例的Java類庫,誕生之初就宣稱是JUnit的下一代產品,事實也確實如此,在功能和易用性方面,TestNG都要強過於4.X及其更早版本的JUnit,網上有很多兩者的對比文章,其中比較有名的一篇如下,感興趣的話大家可以仔細閱讀下:
- JUnit 4 Vs TestNG – Comparison: https://mkyong.com/unittest/junit-4-vs-testng-comparison/
JUnit面對市場份額被TestNG不斷蠶食的情況,研發了更加強大的JUnit 5版本,補齊了能力差距,易用性方面也有了更大的提升。因此大家如果可以選擇的話,我個人推薦大家直接使用JUnit 5,功能和易用性絲毫不遜色,還有廣大的群眾基礎,出現問題也方便更快的搜尋到解決方案。那你用JUnit或者TestNG工具寫完了單元測試用例,怎麼執行呢?你可以在各種IDE(比如Eclipse或者IntelliJ IDEA)使用對應的外掛來幫助執行這些測試用例,當然你甚至都可以不用IDE,配置好依賴,直接命令列執行這些測試用例。
但是如何在Maven專案中自動執行這些步驟呢?這就是maven-surefire-plugin所做的事情了。
maven-surefire-plugin
- maven-surefire-plugin: http://maven.apache.org/surefire/maven-surefire-plugin/
maven-surefire-plugin是Maven內嵌的一個外掛,會幫助你在執行mvn test的時候自動執行用JUnit/TestNG編寫的測試用例。
除了將用例執行結果列印到螢幕上之外,還會在target\surefire-reports
目錄下生成兩種形式的用例執行結果:
但是xml和txt格式的報告檔案不太方便檢視,要是能以html格式展示就好,所以你需要maven-surefire-report-plugin
maven-surefire-report-plugin
- maven-surefire-report-plugin: http://maven.apache.org/surefire/maven-surefire-report-plugin/
maven-surefire-report-plugin的輸入就是maven-surefire-plugin所產生的的xml後者txt格式的用例執行報告,輸出就是html格式的用例執行報告。當你執行surefire-report:report
時,你就會獲得一個html格式的檔案:
內容如下:
是不是感覺很醜?沒有關係,我們可以利用maven-project-info-reports-plugin讓他變得漂亮些。
maven-site-plugin/maven-project-info-reports-plugin
- maven-site-plugin: http://maven.apache.org/plugins/maven-site-plugin/index.html
- maven-project-info-reports-plugin: http://maven.apache.org/plugins/maven-project-info-reports-plugin/usage.html
maven-site-plugin主要作用是幫你迅速生成(site:site)一個站點,並完成站點的部署(site:deploy)和啟動(site:run)。當你執行site:site時,maven會同時呼叫maven-project-info-reports-plugin(所以如非定製要求,你可以不在pom.xml中配置maven-project-info-reports-plugin的依賴),生成一個專案框架結構,類似這種:
其實maven-project-info-reports-plugin還能根據你在pom.xml中配置的<project><reporting><plugins>
配置的report外掛,生成各種各樣的專案報告,比如剛才說的maven-surefire-plugin生成的用例執行報告,和馬上要說的用例覆蓋報告。是不是感覺這裡面展示的報告樣式比直接開啟surefire-report.html好多了?
[Emma/emma-maven-plugin][Jacoco/jacoco-maven-plugin][Cobertura/cobertura-maven-plugin]
- Emma:http://emma.sourceforge.net/
- emma-maven-plugin: https://github.com/sonatype/emma-maven-plugin
- JaCoCo/jacoco-maven-plugin: https://www.eclemma.org/jacoco/index.html
- Cobertura: https://github.com/cobertura/cobertura
- cobertura-maven-plugin: http://www.mojohaus.org/cobertura-maven-plugin/
這坨東西可以分為兩類,一類就是檢查Java用例覆蓋情況的工具,另一類就是為了方便maven專案使用,開發出來的對應maven外掛。其中Emma和emma-maven-plugin都很長時間沒人維護了,所以我fork了這兩個專案,並打算繼續維護,目前為止已經解決了一些常見問題:
- Emma:https://github.com/jiangxincode/Emma
- emma-maven-plugin: https://github.com/jiangxincode/emma-maven-plugin
JaCoCo/jacoco-maven-plugin是同一個團隊(EclEmma)在維護,EclEmma原本是一個Emma在Eclipse上的外掛,但是在外掛開發過程中越來越發現Emma在框架結構上的缺陷無法徹底解決,於是另起爐灶開發了JaCoCo,也就是說EclEmma現在除了名字外已經和Emma沒有關係了。
三類用例覆蓋工具中JaCoCo是最新的,也是對Java 8+新標準支援最好的,但是另外兩個工具也有其特長,大家工作中根據實際情況選擇即可。
遠不止這些
前面介紹了測試用例執行情況和用例覆蓋情況的報告,其實為了提升專案質量,可以提供很多種報告供大家使用,比如靜態檢查的findbugs、PMD等,我之前寫過一個更加全面的工具彙總文章,大家可以參考:
https://www.cnblogs.com/jiangxinnju/p/10010177.html
理論說了一大堆,大家有沒有一種衝動,把這些工具引用到自己的專案中去?這邊有個例子供大家參考: