You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Maven测试中JUnit5的@BeforeAll/@BeforeEach日志无法输出至控制台问题

问题描述

我创建了一个简单的Maven项目来复现问题,相关代码和配置如下:

POM文件

<?xml version="1.0" encoding="UTF-8"?>
<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">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.example</groupId>
  <artifactId>NoLog</artifactId>
  <version>1.0-SNAPSHOT</version>
  <properties>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-engine</artifactId>
      <version>5.9.0</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.2</version>
    </dependency>
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-api</artifactId>
      <version>2.19.0</version>
    </dependency>
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-core</artifactId>
      <version>2.19.0</version>
    </dependency>
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-jcl</artifactId>
      <version>2.19.0</version>
    </dependency>
  </dependencies>
</project>

测试类代码

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

public class TestDemo {

  static Logger log = LogManager.getLogger(TestDemo.class);
  @BeforeAll
  public static void setupClass() {
    log.info("BeforeAll 111 from log.info");
    System.out.println("BeforeAll 111 from print");
    log.info("BeforeAll 222 from log.info");
    System.out.println("BeforeAll 222 from print");
  }

  @BeforeEach
  public void setup() {
    log.info("BeforeEach 111 from log.info");
    System.out.println("BeforeEach 111 from print");
    log.info("BeforeEach 222 from log.info");
    System.out.println("BeforeEach 222 from print");
  }

  @Test
  public void test1() {
    log.info("test1 111 from log.info");
    System.out.println("test 111 from print");
    log.info("test1 222 from log.info");
    System.out.println("test 222 from print");
  }
}

Log4j2配置文件

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
  <Appenders>
    <Console name="LogToConsole" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{YYYY-MM-dd HH:mm:ss} [%t] %-5p %c{1}:%L - %msg%n"/>
    </Console>
  </Appenders>
  <Loggers>
    <Root level="info">
      <AppenderRef ref="LogToConsole"/>
    </Root>
    <Logger name="com.hexagon" level="debug" additivity="false">
      <AppenderRef ref="LogToConsole"/>
    </Logger>
  </Loggers>
</Configuration>

运行结果

执行mvn test命令后,仅能看到@Test方法中的日志和输出,@BeforeAll和@BeforeEach中的内容完全不显示:

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running TestDemo
2023-01-05 09:28:03 [main] INFO  TestDemo:29 - test1 111 from log.info
test 111 from print
2023-01-05 09:28:03 [main] INFO  TestDemo:31 - test1 222 from log.info
test 222 from print
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.004 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS

核心问题

执行mvn test命令时,仅能看到@Test方法中的日志,而@BeforeAll和@BeforeEach中的日志无法输出到控制台,请问原因是什么?如何开启这些日志的输出?


原因分析
  1. Maven Surefire插件版本过低:默认Maven使用的Surefire插件版本可能不兼容JUnit 5,对@BeforeAll、@BeforeEach这类生命周期方法的输出捕获支持不完善,导致这些方法中的输出(包括日志和System.out)被丢弃。
  2. Log4j2初始化延迟:Log4j2默认采用懒加载初始化,第一次调用日志方法时才会加载配置文件。@BeforeAll作为静态方法,执行时机可能早于Log4j2完成初始化的时间,导致早期日志事件无法被正确输出。
解决方案

1. 升级并配置Maven Surefire插件

在POM文件中添加最新版本的Surefire插件,并指定使用JUnit 5引擎:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>3.2.5</version>
            <dependencies>
                <dependency>
                    <groupId>org.junit.platform</groupId>
                    <artifactId>junit-platform-surefire-provider</artifactId>
                    <version>1.9.3</version>
                </dependency>
                <dependency>
                    <groupId>org.junit.jupiter</groupId>
                    <artifactId>junit-jupiter-engine</artifactId>
                    <version>5.9.3</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>

2. 提前初始化Log4j2

在测试类的静态代码块中主动触发Log4j2的初始化,确保@BeforeAll执行前配置已加载:

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.LoggerContext;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

public class TestDemo {

  static Logger log;
  
  static {
      // 主动初始化Log4j2
      LoggerContext context = (LoggerContext) LogManager.getContext(false);
      context.reconfigure();
      log = LogManager.getLogger(TestDemo.class);
  }

  @BeforeAll
  public static void setupClass() {
    log.info("BeforeAll 111 from log.info");
    System.out.println("BeforeAll 111 from print");
    log.info("BeforeAll 222 from log.info");
    System.out.println("BeforeAll 222 from print");
  }

  // 其余代码不变
}

3. 确保Log4j2配置文件位置正确

将log4j2.xml放置在src/test/resources目录下,确保测试类加载时能读取到配置文件。


内容的提问来源于stack exchange,提问作者Reed_Xia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 21:01:53