歡迎訪問我的GitHub
https://github.com/zq2599/blog_demos
內容:所有原創文章分類彙總及配套原始碼,涉及Java、Docker、Kubernetes、DevOPS等;
關於《JUnit5學習》系列
《JUnit5學習》系列旨在通過實戰提升SpringBoot環境下的單元測試技能,一共八篇文章,連結如下:
- 基本操作
- Assumptions類
- Assertions類
- 按條件執行
- 標籤(Tag)和自定義註解
- 引數化測試(Parameterized Tests)基礎
- 引數化測試(Parameterized Tests)進階
- 綜合進階(終篇)
本篇概覽
本文是《JUnit5學習》系列的第二篇,學習一個重要的知識點:Assumptions類,只有瞭解了它們,才好繼續後面的學習,全篇章節如下:
- Assertions和Assumptions簡介
- 寫一段程式碼對比效果
- Assumptions編碼
- 檢視執行結果
原始碼下載
- 如果您不想編碼,可以在GitHub下載所有原始碼,地址和連結資訊如下表所示:
名稱 | 連結 | 備註 |
---|---|---|
專案主頁 | https://github.com/zq2599/blog_demos | 該專案在GitHub上的主頁 |
git倉庫地址(https) | https://github.com/zq2599/blog_demos.git | 該專案原始碼的倉庫地址,https協議 |
git倉庫地址(ssh) | git@github.com:zq2599/blog_demos.git | 該專案原始碼的倉庫地址,ssh協議 |
- 這個git專案中有多個資料夾,本章的應用在junitpractice資料夾下,如下圖紅框所示:
- junitpractice是父子結構的工程,本篇的程式碼在assertassume子工程中,如下圖:
Assertions和Assumptions簡介
Assumptions和Assertions容易混淆,因此這裡通過對比它們來學習:
- Assertions即斷言類,裡面提供了很多靜態方法,例如assertTrue,如果assertTrue的入參為false,就會丟擲AssertionFailedError異常,Junit對丟擲此異常的方法判定為失敗;
- Assumptions即假設類,裡面提供了很多靜態方法,例如assumeTrue,如果assumeTrue的入參為false,就會丟擲TestAbortedException異常,Junit對丟擲此異常的方法判定為跳過;
- 簡單的說,Assertions的方法丟擲異常意味著測試不通過,Assumptions的方法丟擲異常意味著測試被跳過(為什麼稱為"跳過"?因為mvn test的執行結果被標記為Skipped);
寫一段程式碼對比效果
- 用程式碼來驗證的效果最好,如下所示,一共四個方法,assertSuccess不丟擲AssertionFailedError異常,assertFail丟擲AssertionFailedError異常,assumpSuccess不丟擲TestAbortedException異常,assumpFail丟擲TestAbortedException異常
package com.bolingcavalry.assertassume.service.impl;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
@SpringBootTest
@Slf4j
public class AssertAssumpTest {
/**
* 最簡單的成功用例
*/
@Test
void assertSuccess() {
assertEquals(2, Math.addExact(1,1));
}
/**
* 最簡單的失敗用例
*/
@Test
void assertFail() {
assertEquals(3, Math.addExact(1,1));
}
/**
* assumeTrue不丟擲異常的用例
*/
@Test
void assumpSuccess() {
// assumeTrue方法的入參如果為true,就不會丟擲異常,後面的程式碼才會繼續執行
assumeTrue(true);
// 如果列印出此日誌,證明assumeTrue方法沒有丟擲異常
log.info("assumpSuccess的assumeTrue執行完成");
// 接下來是常規的單元測試邏輯
assertEquals(2, Math.addExact(1,1));
}
/**
* assumeTrue丟擲異常的用例
*/
@Test
void assumpFail() {
// assumeTrue方法的入參如果為false,就會丟擲TestAbortedException異常,後面就不會執行了
assumeTrue(false, "未通過assumeTrue");
// 如果列印出此日誌,證明assumpFail方法沒有丟擲異常
log.info("assumpFail的assumeTrue執行完成");
// 接下來是常規的單元測試邏輯,但因為前面丟擲了異常,就不再執行了
assertEquals(2, Math.addExact(1,1));
}
}
- 點選下圖紅框位置執行單元測試:
3. 執行結果如下:
4. 另外,在target目錄,可以看到surefire外掛生成的單元測試報告TEST-com.bolingcavalry.assertassume.service.impl.AssertAssumpTest.xml,如下圖所示,testcase節點中出現了skipped節點:
- 上述對比驗證再次說明Assertions和Assumptions的區別:都用來對比預期值和實際值,當預期值和實際值不一致時,Assertions的測試結果是執行失敗,Assumptions的測試結果是跳過(或者忽略);
Assumptions實戰
弄清楚的Assertions和Assumptions的區別,接下來趁熱打鐵,學習Assumptions類中幾個重要的靜態方法:assumeTrue、assumingThat
- 最簡單的用法如下,可見只有assumeTrue不丟擲異常,後面的log.info才會執行:
@Test
@DisplayName("最普通的assume用法")
void tryAssumeTrue() {
assumeTrue("CI".equals(envType));
log.info("CI環境才會列印的assumeTrue");
}
- assumeTrue可以接受Supplier型別作為第二個入參,如果assumeTrue失敗就會將第二個引數的內容作為失敗提示:
@Test
@DisplayName("assume失敗時帶自定義錯誤資訊")
void tryAssumeTrueWithMessage() {
// 第二個入參是Supplier實現,返回的內容用作跳過用例時的提示資訊
assumeTrue("CI".equals(envType),
() -> "環境不匹配而跳過,當前環境:" + envType);
log.info("CI環境才會列印的tryAssumeTrueWithMessage");
}
效果如下圖:
3. 還有個assumingThat方法,可以接受Executable型別作為第二個入參,如果第一個入參為true就會執行Executable的execute方法,注意assumingThat方法的特點:不丟擲異常,因此其所在的方法不會被跳過,這是和assumeTrue相比最大的區別(assumeTrue一旦入參為false就會丟擲異常,其所在方法就被標記為跳過):
@Test
@DisplayName("assume成功時執行指定邏輯")
void tryAssumingThat() {
// 第二個入參是Executable實現,
// 當第一個引數為true時,執行第二個引數的execute方法
assumingThat("CI".equals(envType),
() -> {
log.info("這一行內容只有在CI環境才會列印");
});
log.info("無論什麼環境都會列印的tryAssumingThat");
}
- 接下來我們們執行上述程式碼,看看效果;
執行Assumptions程式碼
- 先做準備工作,本次實戰的springboot工程名為assertassume,我們們在工程的resources目錄下新增兩個配置檔案:application.properties和application-test.properties,位置如下圖:
2. application-test.properties內容如下:
envType:CI
- application.properties內容如下:
envType:PRODUCTION
- 完整的單元測試類如下,通過註解ActiveProfiles,指定了使用application-test.properties的配置,因此envType的值為CI:
package com.bolingcavalry.assertassume.service.impl;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
import static org.junit.jupiter.api.Assumptions.assumingThat;
@SpringBootTest
@Slf4j
@ActiveProfiles("test")
public class AssumptionsTest {
@Value("${envType}")
private String envType;
@Test
@DisplayName("最普通的assume用法")
void tryAssumeTrue() {
assumeTrue("CI".equals(envType));
log.info("CI環境才會列印的assumeTrue");
}
@Test
@DisplayName("assume失敗時帶自定義錯誤資訊")
void tryAssumeTrueWithMessage() {
// 第二個入參是Supplier實現,返回的內容用作跳過用例時的提示資訊
assumeTrue("CI".equals(envType),
() -> "環境不匹配而跳過,當前環境:" + envType);
log.info("CI環境才會列印的tryAssumeTrueWithMessage");
}
@Test
@DisplayName("assume成功時執行指定邏輯")
void tryAssumingThat() {
// 第二個入參是Executable實現,
// 當第一個引數為true時,執行第二個引數的execute方法
assumingThat("CI".equals(envType),
() -> {
log.info("這一行內容只有在CI環境才會列印");
});
log.info("無論什麼環境都會列印的tryAssumingThat");
}
}
- 執行結果如下圖,可見assume通過,所有資訊都被列印出來了:
- 接下來把程式碼中的ActiveProfiles註解那一行註釋掉,如下圖紅框:
- 執行結果如下,可見tryAssumingThat方法被標記為成功,不過從日誌可見assumingThat的第二個入參executable沒有被執行:
- 至此,Assumptions類的常用方法體驗完成,接下來的章節會繼續學習其他常用類;
你不孤單,欣宸原創一路相伴
歡迎關注公眾號:程式設計師欣宸
微信搜尋「程式設計師欣宸」,我是欣宸,期待與您一同暢遊Java世界...
https://github.com/zq2599/blog_demos