Surefire 只报告从模块到 RunListener 的第一个测试套件
Surefire only reports first test suite from module to RunListener
所以我有一个 TeamCity 和 JUnit 测试,我想写一个 RunListener
到 notify TeamCity in real-time about running tests - TeamCity 只支持开箱即用的 JUnit 批量测试报告。
我有几个套件,用 @RunWith(Suite.class)
注释用于测试的逻辑分组。 TeamCity 正确显示按套件分组的测试。但是,我的问题是 Surefire 只会调用 RunListener.testRunStarted
一次,描述中包含两个套件的名称(但无法将测试归因于任何一个)。
所以我实现了
public class JUnitTeamcityReporter extends RunListener {
/** */
private volatile Description suite;
/** */
@Override public void testRunStarted(Description desc) {
this.suite = desc;
}
/** */
@Override public void testStarted(Description desc) {
System.out.println(String.format("##teamcity[testStarted name='%s' captureStandardOutput='true']",
testName(suite, desc)));
}
...
我已经把它连接到我的 pom.xml
:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M3</version>
<configuration>
<forkCount>0</forkCount>
<properties>
<property>
<name>listener</name>
<value>com.pany.JUnitTeamcityReporter</value>
</property>
</properties>
</configuration>
</plugin>
我运行 maven -Dtest=FirstTestSuite,SecondTestSuite
输出如下:
[INFO] Tests run: 11, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 16.803 s - in com.pany.FirstTestSuite
# I expect that my RunListener will be notified HERE, but it does not happen!
[INFO] Running com.pany.SecondTestSuite
否则,如果每个模块只有一个套件,我的解决方案就可以正常工作。
是否可以让 Surefire 将每个 Suite 正确地报告给 testRunStarted?
不幸的是,似乎没有办法从测试描述中获取当前的 运行ning 套件,所以我不知道如何解决这个问题。
JUnit无法获得此信息,Surefire的扩展能力较差,但可以达到:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M4</version> <!-- upgrade to M4 -->
<configuration>
<workingDirectory>${user.dir}</workingDirectory>
<!-- surefire integration to intercept test suite start: -->
<statelessTestsetInfoReporter
implementation="com.pany.TestSuiteAwareTestsetReporter"/>
<properties>
<property>
<name>listener</name>
<value>com.pany.JUnitTeamcityReporter</value>
</property>
</properties>
</configuration>
<dependencies>
<!-- Add dependency to plugin (for surefire) as well as
compile,test dependency to module (for junit) since they're on different classpaths -->
<dependency>
<groupId>com.pany</groupId>
<artifactId>dev-tools</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</plugin>
和测试套件记者的代码:
public class TestSuiteAwareTestsetReporter extends SurefireStatelessTestsetInfoReporter {
@Override public StatelessTestsetInfoConsoleReportEventListener<WrappedReportEntry, TestSetStats> createListener(
ConsoleLogger log) {
return new ConsoleReporter(log, false, false) {
public void testSetStarting(TestSetReportEntry report) {
MessageBuilder builder = MessageUtils.buffer();
/** @see TestSetStats#concatenateWithTestGroup(MessageBuilder, ReportEntry, boolean) */
JUnitTeamcityReporter.suite = concatenateWithTestGroup(builder, report);
super.testSetStarting(report);
}
};
}
...
所以我有一个 TeamCity 和 JUnit 测试,我想写一个 RunListener
到 notify TeamCity in real-time about running tests - TeamCity 只支持开箱即用的 JUnit 批量测试报告。
我有几个套件,用 @RunWith(Suite.class)
注释用于测试的逻辑分组。 TeamCity 正确显示按套件分组的测试。但是,我的问题是 Surefire 只会调用 RunListener.testRunStarted
一次,描述中包含两个套件的名称(但无法将测试归因于任何一个)。
所以我实现了
public class JUnitTeamcityReporter extends RunListener {
/** */
private volatile Description suite;
/** */
@Override public void testRunStarted(Description desc) {
this.suite = desc;
}
/** */
@Override public void testStarted(Description desc) {
System.out.println(String.format("##teamcity[testStarted name='%s' captureStandardOutput='true']",
testName(suite, desc)));
}
...
我已经把它连接到我的 pom.xml
:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M3</version>
<configuration>
<forkCount>0</forkCount>
<properties>
<property>
<name>listener</name>
<value>com.pany.JUnitTeamcityReporter</value>
</property>
</properties>
</configuration>
</plugin>
我运行 maven -Dtest=FirstTestSuite,SecondTestSuite
输出如下:
[INFO] Tests run: 11, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 16.803 s - in com.pany.FirstTestSuite
# I expect that my RunListener will be notified HERE, but it does not happen!
[INFO] Running com.pany.SecondTestSuite
否则,如果每个模块只有一个套件,我的解决方案就可以正常工作。
是否可以让 Surefire 将每个 Suite 正确地报告给 testRunStarted? 不幸的是,似乎没有办法从测试描述中获取当前的 运行ning 套件,所以我不知道如何解决这个问题。
JUnit无法获得此信息,Surefire的扩展能力较差,但可以达到:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M4</version> <!-- upgrade to M4 -->
<configuration>
<workingDirectory>${user.dir}</workingDirectory>
<!-- surefire integration to intercept test suite start: -->
<statelessTestsetInfoReporter
implementation="com.pany.TestSuiteAwareTestsetReporter"/>
<properties>
<property>
<name>listener</name>
<value>com.pany.JUnitTeamcityReporter</value>
</property>
</properties>
</configuration>
<dependencies>
<!-- Add dependency to plugin (for surefire) as well as
compile,test dependency to module (for junit) since they're on different classpaths -->
<dependency>
<groupId>com.pany</groupId>
<artifactId>dev-tools</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</plugin>
和测试套件记者的代码:
public class TestSuiteAwareTestsetReporter extends SurefireStatelessTestsetInfoReporter {
@Override public StatelessTestsetInfoConsoleReportEventListener<WrappedReportEntry, TestSetStats> createListener(
ConsoleLogger log) {
return new ConsoleReporter(log, false, false) {
public void testSetStarting(TestSetReportEntry report) {
MessageBuilder builder = MessageUtils.buffer();
/** @see TestSetStats#concatenateWithTestGroup(MessageBuilder, ReportEntry, boolean) */
JUnitTeamcityReporter.suite = concatenateWithTestGroup(builder, report);
super.testSetStarting(report);
}
};
}
...