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中的日志无法输出到控制台,请问原因是什么?如何开启这些日志的输出?
原因分析
- Maven Surefire插件版本过低:默认Maven使用的Surefire插件版本可能不兼容JUnit 5,对
@BeforeAll、@BeforeEach这类生命周期方法的输出捕获支持不完善,导致这些方法中的输出(包括日志和System.out)被丢弃。 - 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
相关产品推荐
相关产品推荐

