Oracle 到 PostgreSQL 的参考分区迁移实践

来源: InfoQ - 后端

原文

JUnit团队发布了JUnit 6.0.0(2025年9月30日公开可用),统一了Platform、Jupiter和Vintage的版本号,并将最低Java版本提升至17(对于Kotlin测试代码则是Kotlin 2.2)。此更新增加了对Kotlin suspend测试的原生支持,新的CancellationToken API在ConsoleLauncher中支持快速失败执行,内置Java Flight Recorder(JFR)监听器,跨模块采用JSpecify空值注解,以及切换到FastCSV,用于CSV驱动的参数化测试。Vintage模块仍是用于JUnit 4的桥梁,但现已被弃用。

对于Kotlin用户来说,最明显的改进是直接支持suspend。以前,协程测试经常将主体包装在runBlocking中;使用JUnit 6时,开发者可以在测试和生命周期方法上声明suspend,并直接调用suspending API。这消除了样板代码,使协程测试看起来像它们所练习的生产代码。

考虑以下代码片段:

// Before JUnit 6@Testfun foo() = runBlocking {delay(1000)assertEquals(1, 1)}

// With JUnit 6@Testsuspend fun foo() {delay(1000) // suspend call works directlyassertEquals(1, 1)}

在执行语义方面,JUnit 6为嵌套类定义了一个确定性的、有意不明显的顺序。它还引入了MethodOrderer.Default和ClassOrderer.Default,并将@TestMethodOrder继承到@Nested类中。开发者现在也可以使用@TestClassOrder和@Order为嵌套类施加顺序。

以下示例在SecondaryTests之前运行PrimaryTests:

import org.junit.jupiter.api.*;

@TestClassOrder(ClassOrderer.OrderAnnotation.class)class OrderedNestedTestClassesDemo {

@Nested @Order(1) class PrimaryTests { @Test void test1() {} } @Nested @Order(2) class SecondaryTests { @Test void test2() {} }

}

所有JUnit模块现在都使用JSpecify空值注解来明确指示哪些方法参数、返回类型和字段可以为空。这为IDE提供更好的支持,提高了编译时安全性,并为从正确的可空/非可空类型区分中受益的Kotlin用户提供了更精确的文档。

JUnit 6从不再维护的univocity-parsers库迁移到FastCSV,用于@CsvSource和@CsvFileSource注解。FastCSV速度显著更快,符合RFC 4180标准,没有依赖项,并为格式错误的CSV数据提供更好的错误报告。这一变化提高了CSV解析行为的一致性和整体测试执行性能。

取消和提前退出行为也得到了显著升级。平台现在公开了CancellationToken,启动器将其传递给引擎。开发者可以连接自己的监听器,在第一次失败时取消运行,ConsoleLauncher增加了一个--fail-fast标志,可以自动执行此操作。以下代码片段显示了使用新的LauncherExecutionRequest API的监听器驱动方法。像Jupiter和Suite这样的引擎尊重该令牌,因此执行可以干净地中止。

import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;import static org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder.discoveryRequest;import static org.junit.platform.launcher.core.LauncherExecutionRequestBuilder.executionRequest;

import java.io.PrintWriter;

import org.junit.platform.engine.CancellationToken;import org.junit.platform.engine.TestExecutionResult;import org.junit.platform.launcher.*;import org.junit.platform.launcher.core.LauncherFactory;import org.junit.platform.launcher.listeners.SummaryGeneratingListener;

public class FailFastLauncher {

static void main() { CancellationToken token = CancellationToken.create(); TestExecutionListener failFast = new TestExecutionListener() { @Override public void executionFinished(TestIdentifier id, TestExecutionResult result) { if (result.getStatus() == TestExecutionResult.Status.FAILED) { token.cancel(); } } }; SummaryGeneratingListener summary = new SummaryGeneratingListener(); LauncherDiscoveryRequest discover = discoveryRequest() .selectors(selectClass(FastFailDemoTest.class)) .build(); LauncherExecutionRequest exec = executionRequest(discover) .cancellationToken(token) .listeners(failFast, summary) .build(); try (LauncherSession session = LauncherFactory.openSession()) { session.getLauncher().execute(exec); } summary.getSummary().printTo(new PrintWriter(System.out, true)); }

}

JFR支持现在内置于启动器下的org.junit.platform.launcher.jfr中,取代了旧的junit-platform-jfr构件。开发者可以在启动测试时开始JFR录制,然后在JDK Mission Control或*.jfr工具中检查发现和执行事件,无需添加任何额外依赖项。详细信息记录在用户指南中的“Flight Recorder Support”下。

6.0.0版本移除了长期弃用的junit-platform-runner(JUnit 4运行器)和各种遗留的反射和运行器API。团队建议在IDE/构建工具中使用原生的Plaform集成或直接采用Jupiter;Vintage现在只作为临时的桥接,已被正式弃用。对于要升级到5.x版本的团队,可以参考该迁移wiki。

对于大多数已在使用Java 17和JUnit 5.14的团队来说,采用该新版本应该是一个常规的依赖项升级,随后的工作包括快速的试运行,现代化任何构建插件(例如,Surefire/Failsafe ≥ 3.0),并验证由CSV驱动的测试。Kotlin用户可以通过直接的suspend方法简化协程测试,JFR集成变得更容易采用,以便于性能调查。仍在使用JUnit 4的团队应该计划迁移工作,因为Vintage的弃用标志着那条兼容性路径的结束。

原文链接:JUnit 6.0.0 Ships with Java 17 Baseline, Cancellation API, and Kotlin suspend Support