【问题标题】:JUnit5: Surefire plugin runs JUnit4 tests twiceJUnit5:Surefire 插件运行 JUnit4 测试两次
【发布时间】:2020-10-17 23:50:10
【问题描述】:

我的项目中有 JUnit4 和 JUnit5 测试。问题是当我运行mvn clean install 时,JUnit4 测试运行了两次(JUnit5 测试运行良好,并且只运行一次)。

我的父项目 pom 中有以下 surefire-plugin 配置(仅显示相关依赖项)

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.22.2</version>
  <configuration>
    <threadCount>1</threadCount>
    <properties>
      <property>
        <name>junit</name>
        <value>false</value>
      </property>
    </properties>
  </configuration>
  <dependencies>
    <dependency>
      <groupId>org.apache.maven.surefire</groupId>
      <artifactId>surefire-testng</artifactId>
      <version>2.22.2</version>
    </dependency>
    <dependency>
      <groupId>org.apache.maven.surefire</groupId>
      <artifactId>surefire-junit-platform</artifactId>
      <version>2.22.2</version>
    </dependency>
  </dependencies>
</plugin>
...
...
<dependency>
  <groupId>org.junit.jupiter</groupId>
  <artifactId>junit-jupiter-engine</artifactId>
  <version>5.6.2</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.junit.vintage</groupId>
  <artifactId>junit-vintage-engine</artifactId>
  <version>5.6.2</version>
  <scope>test</scope>
</dependency>
<dependency>
  <!-- needed for https://youtrack.jetbrains.com/issue/IDEA-231927?_ga=2.101965186.223349104.1602977709-1646014256.1600106493 -->
  <groupId>org.junit.platform</groupId>
  <artifactId>junit-platform-launcher</artifactId>
  <version>1.6.2</version>
  <scope>test</scope>
</dependency>

我在子项目中也复制了上面的surefire-plugin,以确保它不会被任何东西覆盖。但是,JUnit4 测试仍然运行了两次。

以下是有效 pom 中的 surefire-plugin 部分 -

<plugin>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.22.2</version>
  <configuration>
    <threadCount>1</threadCount>
    <properties>
      <property>
        <name>junit</name>
        <value>false</value>
      </property>
    </properties>
  </configuration>
  <dependencies>
    <dependency>
      <groupId>org.apache.maven.surefire</groupId>
      <artifactId>surefire-testng</artifactId>
      <version>2.22.2</version>
    </dependency>
    <dependency>
      <groupId>org.apache.maven.surefire</groupId>
      <artifactId>surefire-junit-platform</artifactId>
      <version>2.22.2</version>
    </dependency>
    <dependency>
      <groupId>org.apache.maven.surefire</groupId>
      <artifactId>surefire-junit47</artifactId>
      <version>2.19.1</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>
</plugin

在使用-X 选项进行一些调试时,我认为原因是因为surefire-junit47 也被添加到了surefire-plugin 的提供程序中,surefire-junit-platform 运行一次 junit4 测试,它们由surefire-junit47 提供程序再次运行.如果这是一个可能的原因,那么我该如何防止它被添加到 surefire-plugin 依赖项中?我尝试了 &lt;classpathDependencyExcludes&gt;,但这并没有帮助,有效的 pom 仍然包含surefire-junit47。

即使有两个提供程序(surefire-junit47surefire-junit-platform),还有什么方法可以避免 JUnit4 运行两次?

---------更新------------

我还在配置中将junit 属性设置为false,以防止testng 提供程序运行junit 测试(建议here)。但是,我仍然进行了两次 JUnit4 测试。我的猜测是,不知何故 surefire-junit47(它被神秘地添加了)和 surefire-junit-platform 一起表现得很奇怪,导致重复运行。

---------更新------------

实际的问题是我的项目继承了一个父 pom,它在surefire-plugin 中声明了一个依赖surefire-junit47。如此有效地,我的项目同时具有surefire-junit-platform 和surefire-junit47,这导致了JUnit4 测试的双重运行。

【问题讨论】:

    标签: java maven junit5 maven-surefire-plugin


    【解决方案1】:

    我能够重现您的问题。您遇到了here 描述的情况:

    TestNG 6.5.1 及更高版本支持在当前 Maven 项目中运行 TestNG 和 JUnit 4.x。 (...)

    您可能想要运行两个提供程序,例如surefire-junit47surefire-testng,并通过设置属性 junit=false 避免在 surefire-testng 提供程序中运行 JUnit 测试。

    所以请将您的 Surefire 插件配置更改为:

    <configuration>
      <threadCount>1</threadCount>
      <properties>
        <!-- Avoid running JUnit 4 tests in TestNG engine -->
        <property>
          <name>junit</name>
          <value>false</value>
        </property>
      </properties>
    </configuration>
    

    更新:如何(伪)排除直接 Maven 插件依赖项:

    好的,FWIW 我想出了一个老生常谈的方法来“排除”依赖项,方法是用一个假人覆盖它。

    首先,您将一个模块添加到项目的根 POM,但没有将根 POM 指定为其父级。只要确保模块构建在同一个反应器中即可。或者,您也可以为其创建一个单独的项目,并确保其生成的工件位于您公司的存储库中。

    模块 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.apache.maven.surefire</groupId>
      <artifactId>surefire-junit47</artifactId>
      <version>dummy</version>
    </project>
    

    在您希望停用 JUnit 4.7 引擎以支持在 JUnit 5 平台上运行 JUnit 4 测试的子 POM 中,您可以执行以下操作:

    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-surefire-plugin</artifactId>
      <version>${maven-surefire.version}</version>
      <configuration>
        <threadCount>1</threadCount>
        <properties>
          <!-- Avoid running JUnit 4 tests in TestNG engine -->
          <property>
            <name>junit</name>
            <value>false</value>
          </property>
        </properties>
      </configuration>
      <dependencies>
        <dependency>
          <!-- Deactivate JUnit 4.7 engine by overriding it with an empty dummy -->
          <groupId>org.apache.maven.surefire</groupId>
          <artifactId>surefire-junit47</artifactId>
          <version>dummy</version>
        </dependency>
      </dependencies>
    </plugin>
    
    <!-- (...) -->
    
    <dependencies>
      <dependency>
        <groupId>org.apache.maven.surefire</groupId>
        <artifactId>surefire-junit47</artifactId>
        <version>dummy</version>
      </dependency>
    </dependencies>
    

    这非常难看,如果可能的话,我仍然建议重构父 POM。无论如何,它有效。现在您的 JUnit 4 测试只运行一次,即在 JUnit 5 平台内与 JUnit 5 测试、Spock 2.0 测试或您拥有的其他测试一起运行。


    更新 2: 在您提供 MCVE on GitHub 后,我向您发送了 pull request,这正是我在上一次更新中提到的解决方法。重要的提交是this one

    【讨论】:

    • 嗨@kriegaex,感谢您重现我的问题!实际上,我已经在我的 pom 文件中设置了该属性,并且我仍然运行了两次 JUnit4。我已经更新了我的问题以将此属性也包含在更新的 pom.xml 中。
    • 那么请提供MCVE 让我重现问题。将您的项目压缩为仍然重现问题的最小样本,删除所有不相关的内容。然后将其发布到 GitHub 上并将链接发送给我。我无法调试我看不到的东西。您提供的信息似乎与您相关,但问题必须隐藏在您显示的项目部分中。我有几个想法可能会出错,但我讨厌盲目推测。我已经浪费时间写了一个不必要的答案,因为你隐藏了信息。
    • 感谢@kriegaex,我试图制作一个 MCVE,它也帮助我调试了问题。我发现我的项目的父 pom 已经在surefire-plugin 中定义了surefire-junit47 depedency。 Maven 将其与我的 pom 中的 surfire-plugin 合并,从而在我的项目的 pom 中生成了surefire-junit47 和surefire-junit-platform(这会导致双重运行)。
    • 有没有办法完全覆盖父 pom 中为surefire-plugin 声明的依赖项?我在看combine.self="override",但它似乎只适用于配置。
    • 就像我说的,我喜欢分析,而不是推测。对于您询问的情况,我的回答是正确的。如果您的实际情况更复杂,请按照我的要求展示它。对于我看不到的一组 POM,我不能说任何聪明的事情。我也不太愿意回答 cmets 提出的新问题,只是因为您似乎认为应该以特定方式解决问题。这有成为XY problem 实例的危险。所以请给我看你的,然后我会告诉你我的。 ?
    猜你喜欢
    • 2019-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-21
    • 2022-07-24
    • 2021-05-16
    • 2020-10-14
    • 1970-01-01
    相关资源
    最近更新 更多