ITestContext中MavenProject为空,如何从自定义TestNG监听器读取多模块pom.xml?
问题
我的最终目标是在集成测试模块的自定义TestNG监听器中读取不同模块的所有pom.xml。
- 预期行为:
iTestContext.getAttribute("maven.project")不应为空 - 实际行为:自定义
TestDataCollectListener类的onStart方法中获取到的mavenProject为null
已配置maven-surefire-plugin但无效果,相关代码及配置如下:
自定义监听器代码
public final class TestDataCollectListener implements IExecutionListener, ITestListener, ISuiteListener { @Override public void onStart(final ITestContext iTestContext) { mavenProject = (MavenProject) iTestContext.getAttribute("maven.project"); System.out.println("project found!!"+ mavenProject.getName()); } }
Maven Surefire插件配置
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <suiteXmlFiles> <suiteXmlFile>${suiteXmlFile}</suiteXmlFile> </suiteXmlFiles> <properties> <property> <name>usedefaultlisteners</name> <value>false</value> </property> <property> <name>listener</name> <value>com.abc.test.pqr.TestDataCollectListener</value> </property> </properties> </configuration> </plugin>
请问我遗漏了什么配置或步骤?
解决方案
你漏了两个关键配置,导致Maven没有把MavenProject对象注入到TestNG上下文:
- 禁用测试进程fork
默认情况下Surefire会fork独立进程执行测试,这会切断Maven主进程与测试进程的上下文传递。需要在插件配置中添加:
<forkCount>0</forkCount>
让测试在Maven主进程内运行,确保上下文能正确共享。
- 启用Maven项目信息注入
需要在Surefire的properties里新增属性,明确让插件把Maven项目信息注入到TestNG上下文:
<property> <name>mavenProjectInfo</name> <value>true</value> </property>
- 可选:调整监听器获取时机
IExecutionListener的onExecutionStart方法执行时机早于ITestListener的onStart,可以尝试在这个方法中获取maven.project,避免因时机问题导致获取失败,示例代码:
@Override public void onExecutionStart() { // 若能获取到TestNG上下文,可在此尝试获取MavenProject对象 }
修改后的完整Surefire配置:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <forkCount>0</forkCount> <suiteXmlFiles> <suiteXmlFile>${suiteXmlFile}</suiteXmlFile> </suiteXmlFiles> <properties> <property> <name>usedefaultlisteners</name> <value>false</value> </property> <property> <name>listener</name> <value>com.abc.test.pqr.TestDataCollectListener</value> </property> <property> <name>mavenProjectInfo</name> <value>true</value> </property> </properties> </configuration> </plugin>
内容的提问来源于stack exchange,提问作者Mehul Parmar
相关产品推荐
相关产品推荐

