使用不同的 log4j 配置(设置为调试)重新运行失败的测试?
Rerun failing tests with different log4j config (set to debug)?
我们有一个多模块 Maven 项目,其中每个模块都包含测试。我们有大约 2000 个测试,从单元测试到集成测试。
我们使用 TestNG 和 Log4j
这些集成测试做了很多工作。在开发过程中,我们有时会添加一个System.out.println
来打印一些调试信息。
我知道 syso 通常不是一个好主意,所以我尝试使用 Log4j。
有没有一种简单的方法可以自动重新运行使用不同 log4j 配置的 Maven 和 TestNG 的失败测试
我想出了一个解决方案(基于上面的评论)
- 用于将全局 Log4j 配置设置为
ERROR
的设置
- 设置在第一次重试时将其更改为
DEBUG
,并在 后重置为 ERROR
- 一个转换器,所以我不需要为每个
@Test
更改注释
我实现了三个类:
用法
刚刚 运行: mvn test
pom.xml
的相关部分
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven.surefire.plugin.version}</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
(为了在 maven surefire 中工作,你还需要将这些 类 添加到 testng.xml
)
testng.xml
<suite name="Suite1" verbose="1">
<listeners>
<listener class-name="my.package.RerunBeforeSuiteOnlyError" />
<listener class-name="my.package.RerunTestTransformer" />
</listeners>
...
Re运行BeforeSuiteOnlyError
public class RerunBeforeSuiteOnlyError implements ISuiteListener {
public static final Level DEFAULT_TEST_LOGGING_LEVEL = Level.ERROR;
@Override
public void onStart(final ISuite suite) {
Configurator.setRootLevel(DEFAULT_TEST_LOGGING_LEVEL);
}
@Override
public void onFinish(final ISuite suite) {
}
}
Re运行DebugModifier
public class RerunDebugModifier implements IRetryAnalyzer {
boolean retried = false;
@Override
public boolean retry(final ITestResult result) {
// do we need to retry?
// 1st time YES -> retry with DEBUG level
if (!this.retried) {
Configurator.setRootLevel(Level.DEBUG);
this.retried = true;
return true;
} else {
// 2nd time NO -> reset to ERROR, don't retry
Configurator.setRootLevel(RerunBeforeSuiteOnlyError.DEFAULT_TEST_LOGGING_LEVEL);
return false;
}
}
}
Re运行TestTransformer
public class RerunTestTransformer implements IAnnotationTransformer {
@Override
public void transform(final ITestAnnotation testannotation, final Class testClass, final Constructor testConstructor, final Method testMethod) {
final IRetryAnalyzer retry = testannotation.getRetryAnalyzer();
if (retry == null) {
testannotation.setRetryAnalyzer(RerunDebugModifier.class);
}
}
}
我们有一个多模块 Maven 项目,其中每个模块都包含测试。我们有大约 2000 个测试,从单元测试到集成测试。
我们使用 TestNG 和 Log4j
这些集成测试做了很多工作。在开发过程中,我们有时会添加一个System.out.println
来打印一些调试信息。
我知道 syso 通常不是一个好主意,所以我尝试使用 Log4j。
有没有一种简单的方法可以自动重新运行使用不同 log4j 配置的 Maven 和 TestNG 的失败测试
我想出了一个解决方案(基于上面的评论)
- 用于将全局 Log4j 配置设置为
ERROR
的设置
- 设置在第一次重试时将其更改为
DEBUG
,并在 后重置为 - 一个转换器,所以我不需要为每个
@Test
更改注释
ERROR
我实现了三个类:
用法
刚刚 运行: mvn test
pom.xml
的相关部分 <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven.surefire.plugin.version}</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
(为了在 maven surefire 中工作,你还需要将这些 类 添加到 testng.xml
)
testng.xml
<suite name="Suite1" verbose="1">
<listeners>
<listener class-name="my.package.RerunBeforeSuiteOnlyError" />
<listener class-name="my.package.RerunTestTransformer" />
</listeners>
...
Re运行BeforeSuiteOnlyError
public class RerunBeforeSuiteOnlyError implements ISuiteListener {
public static final Level DEFAULT_TEST_LOGGING_LEVEL = Level.ERROR;
@Override
public void onStart(final ISuite suite) {
Configurator.setRootLevel(DEFAULT_TEST_LOGGING_LEVEL);
}
@Override
public void onFinish(final ISuite suite) {
}
}
Re运行DebugModifier
public class RerunDebugModifier implements IRetryAnalyzer {
boolean retried = false;
@Override
public boolean retry(final ITestResult result) {
// do we need to retry?
// 1st time YES -> retry with DEBUG level
if (!this.retried) {
Configurator.setRootLevel(Level.DEBUG);
this.retried = true;
return true;
} else {
// 2nd time NO -> reset to ERROR, don't retry
Configurator.setRootLevel(RerunBeforeSuiteOnlyError.DEFAULT_TEST_LOGGING_LEVEL);
return false;
}
}
}
Re运行TestTransformer
public class RerunTestTransformer implements IAnnotationTransformer {
@Override
public void transform(final ITestAnnotation testannotation, final Class testClass, final Constructor testConstructor, final Method testMethod) {
final IRetryAnalyzer retry = testannotation.getRetryAnalyzer();
if (retry == null) {
testannotation.setRetryAnalyzer(RerunDebugModifier.class);
}
}
}