Maven Surefire 双重计数测试
Maven Surefire Double-Counting Tests
虽然我不太精通 Maven 生命周期,但我在过去三天阅读了大量文档,但没有发现任何显示构建周期、目标或我的插件与我遇到的问题之间的关系看到了。
我在使用最新的 Surefire 插件 (3.0.0-M1) 时遇到了一个奇怪的问题,我的单元测试成功完成但似乎 运行ning 两次(或者可能只是被计算了两次?).
一些上下文 - 在我在此 POM 文件中指定任何插件或版本之前,Surefire 运行 单独使用默认版本使用:
mvn clean package
我不知道为什么。我从来没有真正停下来问为什么会这样。它总是如此,所以我把它当作 g运行ted,现在它表现得很奇怪。这可能是我应得的。
这是 运行 的 POM 文件(删除了一些属性和分布):
<build>
<sourceDirectory>src/main/java</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.8</version>
<configuration>
<destFile>${basedir}/target/jacoco.exec</destFile>
<dataFile>${basedir}/target/jacoco.exec</dataFile>
</configuration>
<executions>
<execution>
<id>jacoco-initialize</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>jacoco-site</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>true</createDependencyReducedPom>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.capitalone.cardcore.App</mainClass>
</transformer>
</transformers>
<artifactSet>
<excludes>
<artifact>junit:*</artifact>
<artifact>org.hamcrest:*</artifact>
<artifact>org.junit.jupiter:*</artifact>
<artifact>org.apiguardian:*</artifact>
<artifact>org.powermock:*</artifact>
<artifact>org.mockito:*</artifact>
<artifact>commons-beanutils:*</artifact>
<artifact>javax.xml.*</artifact>
<artifact>org.apache.hadoop:hadoop-yarn-client:*</artifact>
<artifact>org.apache.hadoop:hadoop-yarn-server-common:*</artifact>
<artifact>org.apache.hadoop:hadoop-yarn-api:*</artifact>
</excludes>
</artifactSet>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
<exclude>**/*.dll</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.6</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.9</version>
</dependency>
<!-- HTTP -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.4</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
<dependency>
<groupId>com.google.http-client</groupId>
<artifactId>google-http-client</artifactId>
<version>1.23.0</version>
</dependency>
<dependency>
<groupId>com.google.http-client</groupId>
<artifactId>google-http-client-jackson2</artifactId>
<version>1.23.0</version>
</dependency>
<!-- JRECORD -->
<dependency>
<groupId>net.sf.JRecord</groupId>
<artifactId>JRecord</artifactId>
<version>0.81.1</version>
</dependency>
<dependency>
<groupId>net.sf.bruce_a_martin.cb2xml</groupId>
<artifactId>cb2xml</artifactId>
<version>0.95.3</version>
</dependency>
<!-- PGP -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpg-jdk15on</artifactId>
<version>1.47</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.47</version>
</dependency>
<!-- UNIT TESTS -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.0.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-core</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-easymock</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>2.0.2-beta</version>
<scope>test</scope>
</dependency>
<!-- PARQUET OUTPUT -->
<dependency>
<groupId>org.apache.parquet</groupId>
<artifactId>parquet-avro</artifactId>
<version>${parquet.version}</version>
</dependency>
<dependency>
<groupId>org.apache.parquet</groupId>
<artifactId>parquet-common</artifactId>
<version>${parquet.version}</version>
</dependency>
<dependency>
<groupId>org.apache.parquet</groupId>
<artifactId>parquet-encoding</artifactId>
<version>${parquet.version}</version>
</dependency>
<dependency>
<groupId>org.apache.parquet</groupId>
<artifactId>parquet-column</artifactId>
<version>${parquet.version}</version>
</dependency>
<dependency>
<groupId>org.apache.parquet</groupId>
<artifactId>parquet-hadoop</artifactId>
<version>${parquet.version}</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>${hadoop.version}</version>
</dependency>
</dependencies>
所以 - 没有提到 surefire 插件,但它 运行 无论如何我的测试。运行所有测试并返回 144 作为计数(正确)。一年多以来都是这样,但我添加了一些代码调整,现在我需要将其作为插件包含在内,因为我的测试需要一些环境变量,如下所示:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M1</version>
<configuration>
<environmentVariables>
<env>dev</env>
<ENV>DEV</ENV>
</environmentVariables>
</configuration>
</plugin>
但是现在当我 运行 我的测试套件时我得到了这个:
第一个问题是:我是不是疯了?当我不包含该插件时,当我什么都不做时,surefire 插件默认为 运行ning(我什至不知道如何关闭它),当我包含它时,它似乎 运行 两次。我的其他插件之一 运行 没有广播它吗?这是一个我不引以为豪的问题。但是然后 - 如果我将插件作为一个行项目包含在我的 POM 中,但将其设置为 "default" 版本:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.4</version>
<configuration>
<environmentVariables>
<env>dev</env>
<ENV>DEV</ENV>
</environmentVariables>
</configuration>
</plugin>
我得到了预期的 144 计数和我的测试 运行,因为它们具有所需的变量。那么最新版本的surefire可能有问题吗?或者只是我将它包含在其他包中的方式?
有人用这个新的 Surefire 遇到过这个问题吗?或者也许是这种插件组合?
编辑 #1 - 2018 年 11 月 18 日
包括我的测试套件class:
package com.business.cardcore.tests;
import com.business.cardcore.tests.classes.app.*;
import com.business.cardcore.tests.classes.librarytools.*;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@RunWith(Suite.class)
// run the test classes
@Suite.SuiteClasses({
// App
AppCoreTests.class,
AppFileMapperErrorTests.class,
AppFileProcessorErrorTests.class,
AppSchemaWriterErrorTests.class,
// LibraryTools
ChamberOfSecretsTests.class,
ConfigurationTests.class,
CopybookReaderErrorTests.class,
CopybookReaderTests.class,
DatawiseTests.class,
FileMapperTests.class,
HttpWrapperTests.class,
OutputAsciiTests.class,
OutputEbcdicTests.class,
OutputParquetTests.class,
PGPDecryptTests.class,
SchemaWriterTests.class,
TokenValidationTests.class,
TuringTests.class,
ValidationTests.class
})
public class TestSuite { }
请参阅此 answer to Maven: Lifecycle vs. Phase vs. Plugin vs. Goal 的 参考资料 部分,了解为什么插件 运行 在 Maven 构建期间没有声明它们。
关于您的双重测试的疯狂猜测:在您的第一张图片中,我们可以看到您正在 运行宁 TestSuite
。也许您的测试 运行(或计数)一次通过此套件,一次单独进行。如果你 remove/disable 套房怎么办。
虽然我不太精通 Maven 生命周期,但我在过去三天阅读了大量文档,但没有发现任何显示构建周期、目标或我的插件与我遇到的问题之间的关系看到了。
我在使用最新的 Surefire 插件 (3.0.0-M1) 时遇到了一个奇怪的问题,我的单元测试成功完成但似乎 运行ning 两次(或者可能只是被计算了两次?).
一些上下文 - 在我在此 POM 文件中指定任何插件或版本之前,Surefire 运行 单独使用默认版本使用:
mvn clean package
我不知道为什么。我从来没有真正停下来问为什么会这样。它总是如此,所以我把它当作 g运行ted,现在它表现得很奇怪。这可能是我应得的。
这是 运行 的 POM 文件(删除了一些属性和分布):
<build>
<sourceDirectory>src/main/java</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.8</version>
<configuration>
<destFile>${basedir}/target/jacoco.exec</destFile>
<dataFile>${basedir}/target/jacoco.exec</dataFile>
</configuration>
<executions>
<execution>
<id>jacoco-initialize</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>jacoco-site</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>true</createDependencyReducedPom>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.capitalone.cardcore.App</mainClass>
</transformer>
</transformers>
<artifactSet>
<excludes>
<artifact>junit:*</artifact>
<artifact>org.hamcrest:*</artifact>
<artifact>org.junit.jupiter:*</artifact>
<artifact>org.apiguardian:*</artifact>
<artifact>org.powermock:*</artifact>
<artifact>org.mockito:*</artifact>
<artifact>commons-beanutils:*</artifact>
<artifact>javax.xml.*</artifact>
<artifact>org.apache.hadoop:hadoop-yarn-client:*</artifact>
<artifact>org.apache.hadoop:hadoop-yarn-server-common:*</artifact>
<artifact>org.apache.hadoop:hadoop-yarn-api:*</artifact>
</excludes>
</artifactSet>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
<exclude>**/*.dll</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.6</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.9</version>
</dependency>
<!-- HTTP -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.4</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
<dependency>
<groupId>com.google.http-client</groupId>
<artifactId>google-http-client</artifactId>
<version>1.23.0</version>
</dependency>
<dependency>
<groupId>com.google.http-client</groupId>
<artifactId>google-http-client-jackson2</artifactId>
<version>1.23.0</version>
</dependency>
<!-- JRECORD -->
<dependency>
<groupId>net.sf.JRecord</groupId>
<artifactId>JRecord</artifactId>
<version>0.81.1</version>
</dependency>
<dependency>
<groupId>net.sf.bruce_a_martin.cb2xml</groupId>
<artifactId>cb2xml</artifactId>
<version>0.95.3</version>
</dependency>
<!-- PGP -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpg-jdk15on</artifactId>
<version>1.47</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.47</version>
</dependency>
<!-- UNIT TESTS -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.0.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-core</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-easymock</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>2.0.2-beta</version>
<scope>test</scope>
</dependency>
<!-- PARQUET OUTPUT -->
<dependency>
<groupId>org.apache.parquet</groupId>
<artifactId>parquet-avro</artifactId>
<version>${parquet.version}</version>
</dependency>
<dependency>
<groupId>org.apache.parquet</groupId>
<artifactId>parquet-common</artifactId>
<version>${parquet.version}</version>
</dependency>
<dependency>
<groupId>org.apache.parquet</groupId>
<artifactId>parquet-encoding</artifactId>
<version>${parquet.version}</version>
</dependency>
<dependency>
<groupId>org.apache.parquet</groupId>
<artifactId>parquet-column</artifactId>
<version>${parquet.version}</version>
</dependency>
<dependency>
<groupId>org.apache.parquet</groupId>
<artifactId>parquet-hadoop</artifactId>
<version>${parquet.version}</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>${hadoop.version}</version>
</dependency>
</dependencies>
所以 - 没有提到 surefire 插件,但它 运行 无论如何我的测试。运行所有测试并返回 144 作为计数(正确)。一年多以来都是这样,但我添加了一些代码调整,现在我需要将其作为插件包含在内,因为我的测试需要一些环境变量,如下所示:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M1</version>
<configuration>
<environmentVariables>
<env>dev</env>
<ENV>DEV</ENV>
</environmentVariables>
</configuration>
</plugin>
但是现在当我 运行 我的测试套件时我得到了这个:
第一个问题是:我是不是疯了?当我不包含该插件时,当我什么都不做时,surefire 插件默认为 运行ning(我什至不知道如何关闭它),当我包含它时,它似乎 运行 两次。我的其他插件之一 运行 没有广播它吗?这是一个我不引以为豪的问题。但是然后 - 如果我将插件作为一个行项目包含在我的 POM 中,但将其设置为 "default" 版本:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.4</version>
<configuration>
<environmentVariables>
<env>dev</env>
<ENV>DEV</ENV>
</environmentVariables>
</configuration>
</plugin>
我得到了预期的 144 计数和我的测试 运行,因为它们具有所需的变量。那么最新版本的surefire可能有问题吗?或者只是我将它包含在其他包中的方式?
有人用这个新的 Surefire 遇到过这个问题吗?或者也许是这种插件组合?
编辑 #1 - 2018 年 11 月 18 日
包括我的测试套件class:
package com.business.cardcore.tests;
import com.business.cardcore.tests.classes.app.*;
import com.business.cardcore.tests.classes.librarytools.*;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@RunWith(Suite.class)
// run the test classes
@Suite.SuiteClasses({
// App
AppCoreTests.class,
AppFileMapperErrorTests.class,
AppFileProcessorErrorTests.class,
AppSchemaWriterErrorTests.class,
// LibraryTools
ChamberOfSecretsTests.class,
ConfigurationTests.class,
CopybookReaderErrorTests.class,
CopybookReaderTests.class,
DatawiseTests.class,
FileMapperTests.class,
HttpWrapperTests.class,
OutputAsciiTests.class,
OutputEbcdicTests.class,
OutputParquetTests.class,
PGPDecryptTests.class,
SchemaWriterTests.class,
TokenValidationTests.class,
TuringTests.class,
ValidationTests.class
})
public class TestSuite { }
请参阅此 answer to Maven: Lifecycle vs. Phase vs. Plugin vs. Goal 的 参考资料 部分,了解为什么插件 运行 在 Maven 构建期间没有声明它们。
关于您的双重测试的疯狂猜测:在您的第一张图片中,我们可以看到您正在 运行宁 TestSuite
。也许您的测试 运行(或计数)一次通过此套件,一次单独进行。如果你 remove/disable 套房怎么办。