JUnit 5 提供了 LoggingListener 用于捕获测试执行过程中的日志(如 JUL 输出),但需通过 Launcher API 显式注册并配合平台配置启用标准流捕获,不能直接用于 @Test 注解的常规测试运行。
junit 5 提供了 `logginglistener` 用于捕获日志输出(如 java.util.logging 在 info 级别产生的日志),但需通过 launcher api 显式注册并配合平台配置启用标准流捕获,不能直接用于 @test 注解的常规测试运行。
LoggingListener 是 JUnit 5 平台(junit-platform-launcher)中一个预置的 TestExecutionListener 实现,专为捕获 java.util.logging(JUL)日志设计。它不会自动生效——你不能仅靠创建实例(如 LoggingListener.forJavaUtilLogging(Level.INFO))就让日志被拦截;必须将其注册到 Launcher 实例,并确保测试执行环境启用了标准输出/错误捕获。
✅ 正确使用步骤
-
启用平台级输出捕获
在 src/test/resources/junit-platform.properties 中添加:junit.platform.output.capture.stdout=true junit.platform.output.capture.stderr=true
这是前提:LoggingListener 依赖平台底层对 System.out/System.err 的重定向机制来捕获 JUL 日志(因为 JUL 默认将 INFO+ 日志输出到 System.err)。
通过 Launcher API 执行测试并注册 Listener
LoggingListener 必须作为 TestExecutionListener 注册到 Launcher,且测试需通过 Launcher.execute() 启动(而非 IDE 或 Maven Surefire 的默认运行方式)。示例如下:
import org.junit.platform.launcher.*;
import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder;
import org.junit.platform.launcher.core.LauncherFactory;
import org.junit.platform.launcher.listeners.LoggingListener;
import org.junit.platform.engine.discovery.DiscoverySelectors;
public class LoggingTestRunner {
public static void main(String[] args) {
// 构建发现请求:扫描 test 包
LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request()
.selectors(DiscoverySelectors.selectPackage("test"))
.configurationParameter("junit.platform.output.capture.stdout", "true")
.configurationParameter("junit.platform.output.capture.stderr", "true")
.build();
try (LauncherSession session = LauncherFactory.openSession()) {
Launcher launcher = session.getLauncher();
// ✅ 关键:注册 LoggingListener(捕获 JUL INFO 日志)
launcher.registerTestExecutionListeners(
LoggingListener.forJavaUtilLogging(java.util.logging.Level.INFO)
);
TestPlan plan = launcher.discover(request);
launcher.execute(plan); // 执行测试,日志将被监听器捕获并输出到 JUL Handler(如 ConsoleHandler)
}
}
}
? 注意:LoggingListener 本身不“存储”日志,而是将捕获的日志条目转发给当前 JUL 的 Logger(通常为 org.junit.platform.launcher),因此请确保你的 JUL 配置(如 logging.properties)允许该 logger 输出到控制台或文件。
⚠️ 常见误区与注意事项
- ❌ 不适用于 @Test 直接运行:在 IDE 中右键运行单个测试类时,JUnit 5 通常使用 junit-jupiter-engine 的默认执行路径,不会加载你手动注册的 LoggingListener。必须显式使用 Launcher 启动。
- ❌ 不捕获 SLF4J / Logback 日志:LoggingListener 仅适配 java.util.logging。若项目使用 SLF4J,需改用 slf4j-simple 绑定或自定义 TestExecutionListener 拦截 org.slf4j.Logger。
- ✅ 可与其他 Listener 组合使用:例如同时注册 LoggingListener 和自定义 TestExecutionListener,实现日志捕获 + 自定义报告逻辑。
- ? 日志格式说明:LoggingListener 将每条 JUL 日志封装为 ReportEntry,其 keyValuePairs() 包含 "logger"、"level"、"message" 等键,可通过 reportingEntryPublished() 方法进一步解析(但通常无需手动处理)。
✅ 总结
LoggingListener 是 JUnit 5 平台层提供的轻量级日志捕获工具,核心价值在于标准化 JUL 日志的测试集成。要真正启用它,请牢记三点:
① 配置 junit-platform.properties 开启 stdout/stderr 捕获;
② 使用 Launcher API(而非注解驱动方式)执行测试;
③ 显式调用 launcher.registerTestExecutionListeners(...) 注册监听器实例。
完成这三步后,所有测试中通过 java.util.logging.Logger 输出的 INFO 及更高级别日志,将被自动捕获并按 JUL 配置输出,便于断言、调试或生成测试报告。











