前言
相比 junit4 這個相對落後的技術,我寫的博文比較簡短,所以 junit5 我打算稍微深入一下,所以大家會發現我的 junit5 的篇幅是長於 junit4 的
junit5 的結構
platform 提供平臺功能,jupiter 是核心,vintage 用來兼容 junit3 和 junit4
junit5 = junit platform + junit jupiter + junit vintage
Junit5 引入依賴
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<scope>test</scope>
</dependency>
注意
junit5 在 idea 2017.1 版本運行會報錯的,這一點得通過升級 idea 來解決!
https://stackoverflow.com/questions/47831893/intellij-does-not-run-junit5-tests
註解
測試方法的註解執行順序從上到下
並且我們可以發現在 @BeforeAll 註解的方法執行時候不需要執行類的構造器,而 @BeforeEach 必須會實例化一下類,如果執行 @Test 時候存在一個實例化的類就去用他,沒有就自己先去執行類的構造器
- @BeforeAll 所有測試開始前執行,且需要是 static 方法
- @BeforeEach 每個測試方法開始前執行
- @Test 測試的方法
- @AfterEach
- @AfterAll
測試方法相關的註解
- @Nested 寫一個嵌套類,裏頭可以寫測試類,因爲是被嵌套的,優先級低於普通的測試方法
- @Disabled 忽略的測試
- @DisplayName 用來展示測試名字,不加這個著名名字則默認使用方法名作爲測試名字
- @ParameterizedTest
- @RepeatedTest 重複執行測試方法多次
運行器的註解
- @RunWith(xxx.class)
- @SelectPackages
- @IncludePackages
- @SelectClasses
- @Tag
- @IncludeTags
- @ExcludeTags
參數化與數據驅動
ValueSource
話不多說直接看實例 1
下面 @ParameterizedTest 表示參數化測試方法,@NullSource 表示無資源,@EmptySource 表示空資源,@ValueSource 表示有資源,其中含有兩個,實際執行這個方法會被執行 4 遍轉入不同的值
簡單多參建議使用 ValueSource
@ParameterizedTest
@NullSource
@EmptySource
@ValueSource(stirngs = {"1", "2"})
public void demo(String str) {
assert str.equals("1");
}
MethodSource
話不多說再來看實例 2
通過 @ParameterizedTest 標註參數化的測試方法,通過 MethodSource 表名測試數據來源一個測試方法,數據來源方法注意名字一致,然數據來源方法返回數據。
若 @MethodSource 後不加東西,它會默認去找和參數化測試方法同名(重載)的方法
涉及到完整的對象的參數建議使用 MethodSource,推薦使用它來做數據驅動,數據源可以是 yaml,json,csv,xml 等其他,最多的還是 yaml 和 json
@ParameterizedTest
@MethodSource("function1")
public void demo(String str) {
system.out.println(str);
}
public static Stream<String> function1() {
return Stream.of("param1", "param2");
/*
// 這種寫法可以在 arguments 中傳多種不同的參數
return Stream.of(arguments("param1"), arguments("param2"));
*/
}
CsvSource
話不多說來看實例 3
至於 @CsvFileSource 資源來自於外部文件數據(resources)
簡單的數據驅動建議使用 CsvSource
@ParameterizedTest
@CsvSource({
"num1, 1",
"num2, 2",
"num3, 3"
})
public void demo(String str, int n) {
// ...
}
斷言
支持多個條件斷言,傳統測試框架一旦第一個斷言出錯下面的就不再執行了,junit5 支持斷言多個,但需要 jdk8 lambda 表達式的支持
Assertions.assertAll("demo",
() -> assertEquals(1, 2);
() -> assertEquals(2, 2);
() -> assertEquals(2, 3);
);
測試套件
這個測試套件的概念在 junit4 也是有的,在 testng 中可以使用 testng.xml 來做測試套件管理,在 junit5 中可以使用代碼的形式來做,即可運行指定包的測試類
@RunWith(JUnitPlatform.class)
@SuiteDisplayName("This is a test suite")
@SelectPackages("包名")
public class TestSuite {
}
並行問題
使用 mvn 並行
安裝一些 maven 插件,比如 surefile,這個插件可以做到測試類並行,方法並行,甚至可以做到 testng 中 xml 的並行,詳細操作 demo 可以查看 maven 的 surefile 插件官網介紹,mvn 的這個特點在我們持續集成的時候還是蠻有實用性的
mvn -Dtest=Xxx test
mvn -Dtest=Xxx,Y*y test
mvn -Dtest=Xxx#myTest test
mvn -Dsurefile.rerunFailingTestsCount=2 test
動態測試
junit5 提供了動態測試用例編寫的可能,需要 @TestFactory 註解
場景:已經拿到結果的一個數據文件,就可以通過 junit5 動態測試來生成測試用例,並且產生一個很好的測試報告。因此我們知道動態測試是依賴於已經知道結果數據,我們要做的就是寫動態測試代碼去比較,和最終生成一個好看測試報告
@TestFactory
public List<DynamicTest> demo() {
return Arrays.asList(
// 第一個動態測試用例
DynamicTest.dynamicTest("First Test", () -> {
// 邏輯...
Assertions.assertEquals(1, 1);
});
// 第二個動態測試用例
DynamicTest.dynamicTest("Second Test", () -> {
// 邏輯...
Assertions.assertEquals(1, 2);
});
);
}