JUnit 5 XML Report - JUnit 151

JUnit 5 XML Report – JUnit 151

  • Post author:
  • Post category:RD / JUnit
  • Post comments:0 Comments
  • Post last modified:2023-02-18

JUnit 5 XML Report

實現 TestExecutionListener 產生包含測試執行摘要的 XML 報告,開發人員和第三方工具可以使用此報告建立各種格式的測試報告, JUnit 5 XML Example 採用自動化工具來驗證產出結果。

JUnit 5 目前支援建立兩種格式的 XML 報告:

Legacy reporting

傳統測試報告格式。

Open Test Reporting ( JUnit 5.9.x )

新測試報告格式、不可知測試框架和編程語言的集合,目前規範中有兩種格式:

  1. 格式是基於事件的,適用於將事件寫入文件並通過本地套接字或網絡連接流式傳輸事件,JUnit 5 使用這種格式。
  2. 格式類似於現有的測試結果分層表示,使用測試樹及其結果來表示執行結果,舊版 JUnit 報告採用這種格式。

檔案目錄

./
   +- build.gradle
       +- src
           +- test
           |   +- org
           |       +- ruoxue
           |           +- spring_boot_168
           |               +- test
           |                   +- junit5
           |                       +- JUnit5Test.java   

Gradle

build.gradle

增加 JUnit Platform Reporting。

切換新舊格式測試報告。
junit.platform.reporting.open.xml.enabled = true/false

設定輸出目錄。
junit.platform.reporting.output.dir = <path>

修改完後,點右鍵,Gradle -> Refresh Gradle Project 。

buildscript {
	group 'org.ruoxue.spring-boot-168'
	version = '0.0.1-SNAPSHOT'
	ext {
		springBootVersion = '2.1.7.RELEASE'
		junit5Version = '5.7.2'
		junitPlatformVersion = '1.7.2'
	}
}

plugins {
	id 'java-library'
	id 'eclipse'
}

dependencies {
	testImplementation ("org.springframework.boot:spring-boot-starter-test:${springBootVersion}") {
		exclude group: 'junit', module: 'junit'
	}
	testImplementation "org.junit.jupiter:junit-jupiter-api:${junit5Version}"
	testRuntimeOnly "org.junit.platform:junit-platform-commons:${junitPlatformVersion}"
	testRuntimeOnly "org.junit.platform:junit-platform-engine:${junitPlatformVersion}"
    testRuntimeOnly "org.junit.platform:junit-platform-launcher:${junitPlatformVersion}"
    testRuntimeOnly "org.junit.platform:junit-platform-reporting:${junitPlatformVersion}"
	testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${junit5Version}"
	testRuntimeOnly "org.junit.vintage:junit-vintage-engine:${junit5Version}"
}

test {
	useJUnitPlatform()
}

tasks.withType(Test).configureEach {
	def outputDir = reports.junitXml.outputLocation
	jvmArgumentProviders << ({
		[
			"-Djunit.platform.reporting.open.xml.enabled=true",
			"-Djunit.platform.reporting.output.dir=${outputDir.get().asFile.absolutePath}"
		]
	} as CommandLineArgumentProvider)
}

JUnit5Test.java

新增單元測試,用來產生測試報告。

package org.ruoxue.spring_boot_168.test.junit5;

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;
import org.junit.jupiter.api.RepeatedTest;
import org.junit.jupiter.api.RepetitionInfo;
import org.junit.jupiter.api.Test;

@DisplayName("JUnit World")
public class JUnit5Test {

	@BeforeAll
	public static void beforeAll() {
		System.out.println("beforeAll");
	}

	@AfterAll
	public static void afterAll() {
		System.out.println("afterAll");
	}

	@BeforeEach
	public void beforeEach() {
		System.out.println("beforeEach");
	}

	@AfterEach
	public void afterEach() throws Exception {
		System.out.println("afterEach");
	}

	@DisplayName("Hello World")
	@Test
	public void helloWorld() {
		System.out.println("Hello World");
	}

	@DisplayName("Java World")
	@Test
	public void javaWorld() {
		System.out.println("Java World");
	}
	
	@RepeatedTest(3)
	public void repeatedHelloWorld() {
		System.out.println("Hello World");
	}

	@RepeatedTest(3)
	public void repeatedJavaWorld() {
		System.out.println("Java World");
	}

	@RepeatedTest(value = 3, name = "{displayName} {currentRepetition}/{totalRepetitions}")
	public void repeatedHelloWorld_2() {
		System.out.println("Hello World");
	}

	@RepeatedTest(value = 3, name = RepeatedTest.LONG_DISPLAY_NAME)
	public void repeatedHelloWorld_3() {
		System.out.println("Hello World");
	}

	@RepeatedTest(value = 3)
	public void repeatedHelloWorld_4(RepetitionInfo repetitionInfo) {
		System.out.println("Hello World");
		System.out.println("Repetition #" + repetitionInfo.getCurrentRepetition());
		assertEquals(3, repetitionInfo.getTotalRepetitions());
	}
}

Gradle Test 測試​

gradle clean test

輸出目錄 ./build/test-results/test

TEST-org.ruoxue.spring_boot_168.test.junit5.JUnit5Test.xml

<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="JUnit World" tests="17" skipped="0" failures="0" errors="0" timestamp="2022-12-07T07:57:57" hostname="chengdeMacBook-Pro.local" time="0.033">
  <properties/>
  <testcase name="repetition 1 of 3" classname="org.ruoxue.spring_boot_168.test.junit5.JUnit5Test" time="0.001"/>
  <testcase name="repetition 2 of 3" classname="org.ruoxue.spring_boot_168.test.junit5.JUnit5Test" time="0.001"/>
  <testcase name="repetition 3 of 3" classname="org.ruoxue.spring_boot_168.test.junit5.JUnit5Test" time="0.001"/>
  <testcase name="Hello World" classname="org.ruoxue.spring_boot_168.test.junit5.JUnit5Test" time="0.0"/>
  <testcase name="Java World" classname="org.ruoxue.spring_boot_168.test.junit5.JUnit5Test" time="0.0"/>
  <testcase name="repeatedHelloWorld_2() 1/3" classname="org.ruoxue.spring_boot_168.test.junit5.JUnit5Test" time="0.0"/>
  <testcase name="repeatedHelloWorld_2() 2/3" classname="org.ruoxue.spring_boot_168.test.junit5.JUnit5Test" time="0.001"/>
  <testcase name="repeatedHelloWorld_2() 3/3" classname="org.ruoxue.spring_boot_168.test.junit5.JUnit5Test" time="0.0"/>
  <testcase name="repeatedHelloWorld_3() :: repetition 1 of 3" classname="org.ruoxue.spring_boot_168.test.junit5.JUnit5Test" time="0.001"/>
  <testcase name="repeatedHelloWorld_3() :: repetition 2 of 3" classname="org.ruoxue.spring_boot_168.test.junit5.JUnit5Test" time="0.001"/>
  <testcase name="repeatedHelloWorld_3() :: repetition 3 of 3" classname="org.ruoxue.spring_boot_168.test.junit5.JUnit5Test" time="0.0"/>
  <testcase name="repetition 1 of 3" classname="org.ruoxue.spring_boot_168.test.junit5.JUnit5Test" time="0.001"/>
  <testcase name="repetition 2 of 3" classname="org.ruoxue.spring_boot_168.test.junit5.JUnit5Test" time="0.001"/>
  <testcase name="repetition 3 of 3" classname="org.ruoxue.spring_boot_168.test.junit5.JUnit5Test" time="0.001"/>
  <testcase name="repetition 1 of 3" classname="org.ruoxue.spring_boot_168.test.junit5.JUnit5Test" time="0.001"/>
  <testcase name="repetition 2 of 3" classname="org.ruoxue.spring_boot_168.test.junit5.JUnit5Test" time="0.002"/>
  <testcase name="repetition 3 of 3" classname="org.ruoxue.spring_boot_168.test.junit5.JUnit5Test" time="0.001"/>
  <system-out><![CDATA[beforeAll
beforeEach
Java World
afterEach
beforeEach
Java World
afterEach
beforeEach
Java World
afterEach
beforeEach
Hello World
afterEach
beforeEach
Java World
afterEach
beforeEach
Hello World
afterEach
beforeEach
Hello World
afterEach
beforeEach
Hello World
afterEach
beforeEach
Hello World
afterEach
beforeEach
Hello World
afterEach
beforeEach
Hello World
afterEach
beforeEach
Hello World
Repetition #1
afterEach
beforeEach
Hello World
Repetition #2
afterEach
beforeEach
Hello World
Repetition #3
afterEach
beforeEach
Hello World
afterEach
beforeEach
Hello World
afterEach
beforeEach
Hello World
afterEach
afterAll
]]></system-out>
  <system-err><![CDATA[]]></system-err>
</testsuite>
JUnit 5 XML Report 2 JUnit 151
JUnit 5 XML Report 3 JUnit 151

心得分享

JUnit 5 Xml Example 提供 xml 報表範例,可以使用新舊兩種格式來產生 XML 測試報告,設定參數切換特定版本,包括報告的輸出目錄的位置,使用 Gradle Test 命令產生報表。

發佈留言