1. Junit5
1.1 框架
結構上變成了:JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage
- JUnit Platform: Junit Platform是在JVM上啓動測試框架,可以接入各種引擎。
- JUnit Jupiter: JUnit Jupiter提供了JUnit5的新的編程模型,是JUnit5新特性的核心。運行在上面的JUnit Platform中。
- JUnit Vintage: 兼容JUnit4.x,Junit3.x測試引擎。
web測試的話,可以用postman
下面是個簡單的例子:
import org.junit.jupiter.api.Test; //注意這裏使用的是jupiter的Test註解!!
public class TestDemo {
@Test
@DisplayName("第一次測試")
public void firstTest() {
System.out.println("hello world");
}
1.2 註解
Junit5多了很多新的tag
@Test :表示方法是測試方法。但是與JUnit4的@Test不同,他的職責非常單一不能聲明任何屬性,拓展的測試將會由Jupiter提供額外測試
@ParameterizedTest :表示方法是參數化測試,下方會有詳細介紹
@RepeatedTest :表示方法可重複執行,下方會有詳細介紹
@DisplayName :爲測試類或者測試方法設置展示名稱
@BeforeEach :表示在每個單元測試之前執行
@AfterEach :表示在每個單元測試之後執行
@BeforeAll :表示在所有單元測試之前執行
@AfterAll :表示在所有單元測試之後執行
@Tag :表示單元測試類別,類似於JUnit4中的@Categories
@Disabled :表示測試類或測試方法不執行,類似於JUnit4中的@Ignore
@Timeout :表示測試方法運行如果超過了指定時間將會返回錯誤
@ExtendWith :爲測試類或測試方法提供擴展類引用
這裏介紹一下tag。利用 Tag 標籤,用戶可以比較方便地根據標註來分類,並在執行時快速根據分類來針對性地運行測試。在 Junit5 中添加 Tag 是通過 @Tag 註解來實現的
Junit5 也支持直接讀取自定義的註解,比如我們自定義一個註解 QiucaoTag,將 @Tag(“qiucao”) 和 @Test 註解聚合,來簡化標註操作。
@QiucaoTag
void customTag(TestInfo info) {
System.out.println(info.getTags());
}
自定義註解類如下:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Tag("qiucao")
@Test
public @interface QiucaoTag {}
1.3 斷言
除了傳統的assertion外,JUnit5提供了一些新的斷言方式。Assertions.assertThrows() ,配合函數式編程就可以進行使用。
@Test
@DisplayName("異常測試")
public void exceptionTest() {
ArithmeticException exception = Assertions.assertThrows(
//扔出斷言異常
ArithmeticException.class, () -> System.out.println(1 % 0));
}
Junit5還提供了Assertions.assertTimeout() 爲測試方法設置了超時時間
@Test
@DisplayName("超時測試")
public void timeoutTest() {
//如果測試方法時間超過1s將會異常
Assertions.assertTimeout(Duration.ofMillis(1000), () -> Thread.sleep(500));
}
1.4 參數化測試
@ValueSource:指定入參,支持八大基礎類以及String類型,Class類型
@NullSource: 表示爲參數化測試提供一個null的入參
@EnumSource: 表示爲參數化測試提供一個枚舉入參
下面是例子
@ParameterizedTest
@ValueSource(strings = {"one", "two", "three"})
@DisplayName("參數化測試1")
public void parameterizedTest1(String string) {
System.out.println(string);
Assertions.assertTrue(StringUtils.isNotBlank(string));
}
1.5 測試用例參數化
Junit5中支持給測試方法提供參數,提高了測試數據管理的便利性。內建的幾種數據源
// ValueSource
@ParameterizedTest
@ValueSource(ints = { 1, 2, 3 })
void testWithValueSource(int argument) {
assertTrue(argument > 0 && argument < 4);
}
//EnumSource
@ParameterizedTest
@EnumSource(TimeUnit.class)
void testWithEnumSource(TimeUnit timeUnit) {
assertNotNull(timeUnit);
}
//還可以提供數據的例外處理,正則匹配等
@ParameterizedTest
@EnumSource(value = TimeUnit.class, mode = EXCLUDE, names = { "DAYS", "HOURS" })
void testWithEnumSourceExclude(TimeUnit timeUnit) {
assertFalse(EnumSet.of(TimeUnit.DAYS, TimeUnit.HOURS).contains(timeUnit));
assertTrue(timeUnit.name().length() > 5);
}
//or
@ParameterizedTest
@EnumSource(value = TimeUnit.class, mode = MATCH_ALL, names = "^(M|N).+SECONDS$")
void testWithEnumSourceRegex(TimeUnit timeUnit) {
String name = timeUnit.name();
assertTrue(name.startsWith("M") || name.startsWith("N"));
assertTrue(name.endsWith("SECONDS"));
}
//MethodSource
@ParameterizedTest
@MethodSource("stringProvider")
void testWithSimpleMethodSource(String argument) {
assertNotNull(argument);
}
static Stream<String> stringProvider() {
return Stream.of("foo", "bar");
}
//CsvSource
@ParameterizedTest
@CsvSource({ "foo, 1", "bar, 2", "'baz, qux', 3" })
void testWithCsvSource(String first, int second) {
assertNotNull(first);
assertNotEquals(0, second);
}
//CsvFileSource
@ParameterizedTest
@CsvFileSource(resources = "/two-column.csv", numLinesToSkip = 1)
void testWithCsvFileSource(String first, int second) {
assertNotNull(first);
assertNotEquals(0, second);
}
2. Allure
2.1 創建junit測試的方法
在要測試的類上按快捷鍵ctrl + shift + t,選擇Create New Test,在出現的對話框的下面member內勾選要測試的方法,點擊ok
或者點擊菜單欄Navigate–>test,選擇Create New Test,在出現的對話框的下面member內勾選要測試的方法,點擊ok
2.2 Allure安裝與配置。
詳細安裝步驟看這裏
首先把junit配置好,去intelliJ idea->Preference->Plugins中,安裝MavenTestSupportPlugin。然後選中要單元測試的項目,按command+shift+t生成test。注意junit5還要再安裝兩個庫。
brew install allure #進行安裝
allure --version # 查看版本號
#這個命令最常使用的,生成web報告。
allure serve [path of allure result]
# 生成測試報告,可以攜帶一個 -c 參數先清空之前的結果。
allure generate [path of allure result]
# 打開已經生產的測試報告:這個命令則會啓動一個 Web 服務將打開。
3. mockito
mockito可以模擬真實環境,Mock測試就是在測試的過程中,對於某些不容易構造的,如HttpServletRequest必須在Servlet容器中才能構造出來,或者不容易獲取比較複雜的對象(如JDBC中的ResultSet對象),用一個虛擬的對象(Mock對象)來創建以便測試的測試方法
Mock最大的功能是幫你把單元測試的耦合分解開,如果你的代碼對另一個類或者接口有依賴,他能幫你模擬這些依賴,並幫你驗證所調用的依賴的行爲
import org.junit.Test;
import java.util.LinkedList;
import static org.mockito.Mockito.*;
public class test {
LinkedList linkedList = mock(LinkedList.class);
@Test
public void test(){
//創建linkedlist
System.out.println(linkedList.get(0)); //null
}
//方法調用的方繪製
@Test
public void test2(){ //模擬方法的調用的返回值
when(linkedList.get(0)).thenReturn("first"); //當調用get(0)是返回first
System.out.println(linkedList.get(0)); //輸出first
}
//方法調用拋出異常
//模擬獲取第二個元素時,拋出runtimeException
@Test
public void test3(){
when(linkedList.get(1)).thenReturn(new RuntimeException());
System.out.println(linkedList.get(1));
}
//調用方法時的參數匹配
@Test
public void test4(){
when(linkedList.get(anyInt())).thenReturn("element");
System.out.println(linkedList.get(100)); //返回element -任意index都會返回element
}
```