單元測試(unit testing),是指對軟體中的最小可測試單元進行檢查和驗證。
總的來說,單元就是人為規定的最小的被測功能子產品。單元測試是在軟體開發過程中要進行的最低級别的測試活動,軟體的獨立單元将在與程式的其他部分相隔離的情況下進行測試。
那單元測試架構該怎麼搭呢?Junit5又能給我們帶來怎樣的驚喜呢?首先我們來看看什麼是Junit5,再看看如何使用吧~
What is Junit5?
Junit5簡介
什麼是Junit5,在Junit5的官方介紹文檔中這寫到:Junit5由JUnit Platform + JUnit Jupiter + JUnit Vintage3部分構成
借用IBM Developer的一張圖來說明JUnit 5 的架構:
JUnit Platform :
其主要作用是在 JVM 上啟動測試架構。它定義了一個抽象的 TestEngine API 來定義運作在平台上的測試架構;也就是說其他的自動化測試引擎或開發人員⾃⼰定制的引擎都可以接入 Junit 實作對接和執行。同時還支援通過指令行、Gradle 和 Maven 來運作平台(這對于我們做自動化測試至關重要)
JUnit Jupiter:
這是 Junit5 的核心,可以看作是承載 Junit4 原有功能的演進,包含了 JUnit 5 最新的程式設計模型和擴充機制;很多豐富的新特性使 JUnit ⾃動化測試更加方便、功能更加豐富和強大。也是測試需要重點學習的地方;Jupiter 本身也是⼀一個基于 Junit Platform 的引擎實作,對 JUnit 5 而言,JUnit Jupiter API 隻是另一個 API!
JUnit Vintage:
Junit 發展了10數年,Junit 3 和 Junit 4 都積累了大量的⽤使用者,作為新一代架構,這個子產品是對 JUnit3,JUnit4 版本相容的測試引擎,使舊版本 junit 的⾃動化測試腳本也可以順暢運行在 Junit5 下,它也可以看作是基于 Junit Platform 實作的引擎範例。
JUnit 5 對 Java 運作環境的最低要求是 Java 8。
Junit5的新特性
特性與JUnit4注解比較
JUnit5的 新特性有:嵌套單元測試、Lambda支援、參數化測試、重複測試、動态測試
JUnit 4 與 JUnit 5 中的注解比較
Junit5 | Junit4 | 說明 |
@Test | @Test | 被注解的方法是一個測試方法。與 JUnit 4 相同。 |
@BeforeAll | @BeforeClass | 被注解的(靜态)方法将在目前類中的所有 @Test 方法前執行一次。 |
@BeforeEach | @Before | 被注解的方法将在目前類中的每個 @Test 方法前執行。 |
@AfterEach | @After | 被注解的方法将在目前類中的每個 @Test 方法後執行。 |
@AfterAll | @AfterClass | 被注解的(靜态)方法将在目前類中的所有 @Test 方法後執行一次。 |
@Disabled | @Ignore | 被注解的方法不會執行(将被跳過),但會報告為已執行。 |
JUnit 5 常用注解
Junit5常用注解展示
注解 | 說明 |
@Test | 表明一個測試方法 |
@DisplayName | 測試類或方法的顯示名稱 |
@BeforeEach | 表明在單個測試方法運作之前執行的方法 |
@AfterEach | 表明在單個測試方法運作之後執行的方法 |
@BeforeAll | 表明在所有測試方法運作之前執行的方法 |
@AfterAll | 表明在所有測試方法運作之後執行的方法 |
@Disabled | 禁用測試類或方法 |
@Tag | 為測試類或方法添加标簽 |
@RepeatedTest | 額外重複執行 |
@Nested | 嵌套測試 |
實操示範
1)建立maven工程XUnit,pom.xml中添加Junit5的依賴
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.5.2</version>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-runner</artifactId>
<version>1.5.1</version>
</dependency>
複制代碼
2)其餘的XUnit架構通用的設計運作規則可參考部落格: 如何利用xUnit架構對測試用例進行維護-xUnit簡介及基本使用方法(基于Junit4)
3)添加用例@Test,再在用例執行前後添加@BeforeEach、@AfterEach:
運作結果:
4)在測試類執行前後添加@BeforeAll和@AfterAll
測試結果:
5)在測試用例test1上加入注解@Disabled,使test1失
測試結果:
從測試結果中我們可以看到test1用例被ignore,沒有被執行
6)分别将test1和test2用@DisplayName加上用例展示名稱
測試結果:
7)對測試用例2加上注解@RepeatedTest,使其額外重複執行3次
測試結果:
從測試結果中我們可以看到測試用例2被額外重複執行了3次
8)對于@Nested嵌套執行舉例如下:
測試結果:
由測試結果可以看出,@Nested的執行順序為先執行@Nested嵌套外層的用例,再以倒叙形式執行@Nested用例,然後再執行第二層嵌套的用例:
外層->倒叙嵌套->第二層嵌套
Junit5套件執行
套件介紹
注解 | 作用 |
@RunWith(JUnitPlatform.class) | 執行套件 |
@SelectPackage({“com.packageA”,“com.packageB”}) | 建立測試套件 |
@SelectClasses( {a.class,b.class,c.class} ) | 建立測試套件 |
@IncludePackage(“包名”) | 過濾需要執行的測試包 |
@ExcludePackages | 過濾不需要執行的測試包 |
@IncludeClassNamePatterns | 過濾需要執行的測試類 |
@ExcludeClassNamePatterns | 過濾不需要執行的測試類 |
@IncludeTags(“production”) | 過濾需要執行的測試方法 |
@ExcludeTags(“PROD”) | 過濾不需要執行的測試方法 |
@RunWith 是從Junit4遷移過來的,@RunWith 連同它的參數 JUnitPlatform.class(一個基于 JUnit 4 且了解 JUnit Platform 的 Runner)讓您可以在 Eclipse 内運作 JUnit Jupiter 單元測試。Eclipse 尚未原生支援 JUnit 5。未來,Eclipse 将提供原生的 JUnit 5 支援,那時我們不再需要此注解;Junit5官方給出了替代它的注解:
@RunWith+@SelectPackages 有兩個包testcasedemo, junit5demo,利用@RunWith+@SelectPackages将包中測試類依次運作
套件類:
測試結果:
@RunWith+@SelectPackages+@IncludePackage
@RunWith+@SelectPackages+@IncludePackages配合使用過濾出需要執行的測試包testcasedemo.demo2
套件類:
測試結果:
@RunWith+@SelectPackages+@ExcludePackages
@RunWith+@SelectPackages+@ExcludePackages配合使用過濾出不需要執行的測試包testcasedemo.demo2
套件類:
測試結果:
@RunWith+@SelectPackages+@IncludeClassNamePatterns
将junit5demo包下的TestJunit5demo和testcasedemo.demo2所有測試類過濾出來并執行
套件類:
測試結果
@RunWith+@SelectPackages+@IncludeTags 在testcasedemo.demo2.TestDemo2的方法testDemo2上加上注解@Tag:
過濾并執行方法testDemo2:
套件類:
測試結果:
參考文檔
Junit5官網:
https://junit.org/junit5/docs/current/user-guide/#overview
IBM Developer:
https://www.ibm.com/developerworks/cn/java/j-introducing-junit5-part1-jupiter-api/index.html
https://www.ibm.com/developerworks/cn/java/j-junit5/index.html