2024年7月17日 星期三

JUnit 5 - 安裝及使用

這裡紀錄下 Java 的 JUnit 5 使用方式,注意 JUnit 5 跟 JUnit 4 有比較大的不同,
例如 Annotation 不同、使用的 asserEquals() 等 method 輸入參數和使用的 package 都有所不同,
詳細可參考 

從 JUnit 4 轉移至 JUnit 5:重要差異與好處. JUnit 5 令人注目的改善與新功能 | by Du Spirit | Java Magazine 翻譯系列 | Medium。

Junit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage

  • Junit Jupiter : 
    • JUnit 5 的主要 Dependency,內部依賴包括了跟 @Test 注解等相關的 junit-jupiter-api 和跟運行測試相關的 junit-jupiter-engine (其實 junit-jupiter-engine 也依賴了 junit-jupiter-api)
  • Junit Vintage :
    • Junit Vintage 是用來運行舊版的 JUnit 4 用的,如果專案沒有使用到 Junit 4 的話可以不使用,不過如果專案沒有使用 Jnit 4 又加上 Junit Vintage 的 Dependency 的話可能會跟 Junit 5 衝突產生如下錯誤 : "TestEngine with ID 'junit-vintage' failed to discover tests"
  • Junit Platform :
    • junit-platform-runner 是專門給一些只支援 Junit 4 但不支援 Junit 5 的 System 或 IDE 用的, 例如舊版不支援 JUnit 5 的 Eclipse,需要為其加上 junit-platform-runner 這個 dependency 並 搭配 @RunWith(JunitPlatform.class) 後, 對專案按右鍵選 Run As 才會有 Junit Test 的按鈕可選。 <dependency>

在 Maven 的 pom.xml 加上:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  ......
  
  <build>
    ......
	<!-- 如果不是標準的 maven 專案結構,請在這裡自行設定 test case 的資料夾和相關 test resource 的資料夾 -->
    <testSourceDirectory>test</testSourceDirectory>
    <testResources>
		<testResource>
			<directory>test</directory>
		</testResource>
	</testResources>
	
    <plugins>
	  ......
	  <!-- Maven 執行 test 的 plugin,surefire 多用於單元測試 (unit test), failsafe 多用於整合測試 (integration test)  -->
	  <plugin>
		<artifactId>maven-surefire-plugin</artifactId>
		<version>3.1.2</version>
      </plugin>
      <plugin>
        <artifactId>maven-failsafe-plugin</artifactId>
        <version>3.1.2</version>
      </plugin>
	  ......
    </plugins>
  </build>

  <dependencyManagement>
	  <dependencies>
	      ......
		  <!-- 可以在這統一設定 junit 相關 dependency 的 version,之後後面就不用特別指定 version -->
		  <dependency>
			  <groupId>org.junit</groupId>
			  <artifactId>junit-bom</artifactId>
			  <version>5.10.3</version>
			  <type>pom</type>
			  <scope>import</scope>
		  </dependency>
		  ......
	  </dependencies>
  </dependencyManagement>

  <dependencies>
    ......
	
	<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter -->
	<!-- JUnit 5 的主要 Dependency,內部依賴包括了跟 @Test 注解等相關的 junit-jupiter-api 和跟運行測試相關的 junit-jupiter-engine (其實 junit-jupiter-engine 也依賴了 junit-jupiter-api) -->
	<dependency>
	    <groupId>org.junit.jupiter</groupId>
	    <artifactId>junit-jupiter</artifactId>
	    <scope>test</scope>
	</dependency>
	
	<!-- https://mvnrepository.com/artifact/junit/junit -->
	<!-- 這是舊版的 JUnit 4 (JUnit 5 以前),可以不使用,不過如果舊專案有用也可以留著
	<dependency>
	    <groupId>junit</groupId>
	    <artifactId>junit</artifactId>
	    <version>4.13</version>
	    <scope>test</scope>
	</dependency>
	-->
	
	<!-- https://mvnrepository.com/artifact/org.junit.vintage/junit-vintage-engine -->
	<!-- junit-vintage-engine 是用來運行舊版的 JUnit 4 用的,可以不使用,不過如果舊專案有用也可以留著,
    如果沒有使用 Jnit 4 的話可能會跟 Junit 5 衝突產生如下錯誤
    TestEngine with ID 'junit-vintage' failed to discover tests
	<dependency>
	    <groupId>org.junit.vintage</groupId>
	    <artifactId>junit-vintage-engine</artifactId>
	    <scope>test</scope>
	</dependency>
	-->
    
    <!-- https://mvnrepository.com/artifact/org.junit.platform/junit-platform-runner -->
	<!-- junit-platform-runner 是專門給一些只支援 Junit 4 但不支援 Junit 5 的 System 或 IDE 用的,
            例如舊版不支援 JUnit 5 的 Eclipse,需要為其加上 junit-platform-runner 這個 dependency 並
            搭配 @RunWith(JunitPlatform.class) 後,
            對專案按右鍵選 Run As 才會有 Junit Test 的按鈕可選。
	<dependency>
		<groupId>org.junit.platform</groupId>
		<artifactId>junit-platform-runner</artifactId>
		<scope>test</scope>
	</dependency>
	-->
	......
  </dependencies>  
</project>

測示範例:

package test.dao;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;



class DaoTest {
	
	@BeforeAll
	static void beforeAll() {
		System.out.println("beforeAll");
	}
	
	@BeforeEach
	void beforeEach() {
		System.out.println("beforeEach");
	}
	
	@Test
	@DisplayName("test1")
	void test1() {
		System.out.println("test1");
		assertEquals(1, 1, "OK");
	}
	
	@Test
	@DisplayName("test2")
	void test2() {
		System.out.println("test2");
		assertEquals(1, 1, "OK");
	}
	
	@AfterEach
	void afterEach() {
		System.out.println("afterEach");
	}
	
	@AfterAll
	static void afterAll() {
		System.out.println("afterAll");
	}
}

上述執行的順序會是如下,@BeforeAll 會在所有 @Test 之前執行、@AfterAll 則是在所有 @Test 之後執行、@BeforeEach 會在每一個 @Test 之前執行、@AfterEach 會在每一個 @Test 之後執行:

  1. beforeAll
  2. beforeEach
  3. test1
  4. afterEach
  5. beforeEach
  6. test2
  7. afterEach
  8. afterAll

參考資料:

沒有留言 :

張貼留言