9

我在尝试配置 Maven 以排除基于多个配置文件的某些类别的单元测试时遇到问题。

我为单元测试定义了两个类别:SlowTest那些需要很长时间才能运行WindowsTest的单元测试,以及那些只能在 Windows 环境中执行的单元测试。

我在项目pom.xml文件中定义了两个配置文件,如下所示:

<profiles>
  <!-- Exclude any tests in `SlowTest` category when profile 'skipSlowTests' is specified. -->
  <profile>
    <id>skipSlowTests</id>
    <activation>
      <activeByDefault>false</activeByDefault>
    </activation>
    <build>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-surefire-plugin</artifactId>
          <configuration>
            <excludedGroups>SlowTest.class</excludedGroups>
          </configuration>
        </plugin>
      </plugins>
    </build>
  </profile>  

  <!-- Skip any tests in 'WindowsTest' category when not running on Windows. -->
  <profile>
    <id>skipWindowsTests</id>
    <activation>
      <os><family>!windows</family></os>
    </activation>
    <build>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-surefire-plugin</artifactId>
          <configuration>
            <excludedGroups>WindowsTest.class</excludedGroups>
          </configuration>
        </plugin>
      </plugins>
    </build>
  </profile>  

</profiles>

因此,例如,当我想运行测试并排除任何慢速测试时,我可以执行mvn -PskipSlowTests test. 如果我想跳过任何 Windows 测试,我可以mvn test在非 Windows 操作系统上执行(或-PskipWindowsTests在命令行上明确指定)。

这里的问题是,当skipSlowTestsskipWindowsTests配置文件都被激活时,只有 Windows 测试被跳过。缓慢的测试仍在运行。当 maven 构造有效pom.xml文件时,它会应用skipSlowTests配置文件并配置maven-surefire-plugin以排除组SlowTest.class。然后skipWindowsTests应用配置文件,这会将排除的组覆盖为WindowsTest.class.

我真正想要的是SlowTest.class,WindowsTest.class当两个配置文件都被激活时被排除的组,但我无法找到一种方法来做到这一点。

我无法在 Maven 中看到将值附加到属性,例如

<properties>
  <excludedGroups>IgnoreTest.class</excludedGroups>
</properties>

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <configuration>
    <excludedGroups>${excludedGroups}</excludedGroups>
  </configuration>
</plugin>

<profile>
  <id>skipSlowTests</id>
  <property>
    <excludedGroups>${excludedGroups},SlowTest.class</excludedGroups>
  </property>
  ...
</profile>

<profile>
  <i>skipWindowsTests</id>
  <property>
    <excludedGroups>${excludedGroups},WindowsTest.class</excludedGroups>
  </property>
  ...
</profile>

这被破坏了,因为在为属性pom.xml赋值时存在递归。excludedGroups

并且没有办法设置第三个配置文件(例如skipSlowTestsAndWindowsTests),只要skipSlowTestsskipWindowsTests都被激活,它就会激活。

这里有什么建议吗?也许添加单独的阶段maven-surefire-plugin(一个用于慢速测试,一个用于 Windows 测试,一个用于所有其他测试)并使用配置文件来确定哪些阶段运行?

编辑#1

我尝试为以下创建单独的执行阶段maven-surefire-plugin

<!-- By default, do not skip slow tests or windows tests -->
<properties>
  <skipSlowTests>false</skipSlowTests>
  <skipWindowsTests>false</skipWindowsTests>
</properties>

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <executions>
    <!-- Default execution will skip SlowTest and WindowsTest categories -->
    <execution>
      <id>default-test</id>
      <phase>test</phase>
      <goals>
        <goal>test</goal>
      </goals>
      <configuration>
        <excludedGroups>SlowTest,WindowsTest</excludedGroups>
      </configuration>
    </execution>
    <!-- Slow Test execution will run the slow tests only (if not skipped) -->
    <execution>
      <id>slow-test</id>
      <phase>test</phase>
      <goals>
        <goal>test</goal>
      </goals>
      <configuration>
        <skip>${skipSlowTests}</skip>
        <groups>SlowTest</groups>
      </configuration>
    </execution>
    <!-- Windows Test execution will run the windows tests only (if not skipped) -->
    <execution>
      <id>windows-test</id>
      <phase>test</phase>
      <goals>
        <goal>test</goal>
      </goals>
      <configuration>
        <skip>${skipWindowsTests}</skip>
        <groups>WindowsTest</groups>
      </configuration>
    </execution>
  </executions>
</plugin>

<profiles>
  <!-- Skip slow tests when skipSlowTests profile enabled -->
  <profile>
    <id>skipSlowTests</id>
    <properties>
      <skipSlowTests>true</skipSlowTests>
    </properties>
  </profile>
  <!-- Skip windows tests when skipWindowsTests profile enabled -->
  <profile>
    <id>skipWindowsTests</id>
    <properties>
      <skipWindowsTests>true</skipWindowsTests>
    </properties>
    ...
  </profile>
</profiles>

此配置将在三个单独的执行中运行测试:default-test执行将运行每个测试,除了慢速测试和 windows 测试;执行slow-test将只运行慢速测试;并且windows-test执行将仅运行 Windows 测试。如果同时启用了skipSlowTestsskipWindowsTests配置文件,则将跳过慢速测试和 Windows 测试。

这里的问题是当有一个测试同时标有SlowTestWindowsTest类别时:

@Test @Category({SlowTest.class,WindowsTest.class})
public void slowWindowsTestCase() { ... }

skipSlowTests仅启用配置文件时,windows-test执行仍会运行,并且由于该slowWindowsTestCase方法被标记为 windows 测试,因此即使我们想跳过慢速测试,它也会被执行。同样,这个测试用例也将在skipWindowsTests仅启用配置文件时执行。跳过此测试用例的唯一方法是同时指定skipSlowTestsskipWindowsTests配置文件。

我尝试如下修改执行:

    <execution>
      <id>slow-test</id>
        ... 
        <groups>SlowTest</groups>
        <excludedGroups>WindowsTest</excludedGroups>
        ...
    </execution>
    <execution>
      <id>windows-test</id>
        ... 
        <groups>WindowsTest</groups>
        <excludedGroups>SlowTest</excludedGroups>
        ...
    </execution>

但是现在该slowWindowsTestCase方法永远不会执行。

编辑#2

即使我可以让测试执行正常工作,我也需要添加一个依赖项,maven-surefire-plugin以便在测试期间可以加载SlowTest和接口。WindowsTest我已经放入maven-surefire-pluginpluginManagement我父 POM 的部分,但是为此插件定义的任何依赖项都不能有test范围。因此,在定义SlowTestWindowsTest接口的模块之外运行测试将不起作用。我可以test在配置文件中为插件添加范围依赖项,但这不会涵盖没有配置文件处于活动状态的情况。

4

2 回答 2

1

您可以使默认配置文件排除所有组,并且对于每个配置文件,您添加一个故障安全/安全插件的执行,仅包括一个组。

于 2015-08-10T18:34:03.773 回答
0

让每个配置文件定义一个属性excludedGroups并在 POM 执行开始时将它们连接到一个属性中怎么样?

<build>
  ...
  <plugin>
    <groupId>org.codehaus.gmavenplus</groupId>
    <artifactId>gmavenplus-plugin</artifactId>
    <version>1.6</version>
    <dependencies>
      <dependency>
        <groupId>org.codehaus.groovy</groupId>
        <artifactId>groovy-all</artifactId>
        <version>2.4.9</version>
        <scope>runtime</scope>
      </dependency>
    </dependencies>
    <executions>
      <execution>
        <id>excludedGroups</id>
        <phase>initialize</phase>
        <goals>
          <goal>execute</goal>
        </goals>
        <configuration>
          <scripts>
            <script>
              <![CDATA[
              def groups = ""
              (project.activeProfiles).each{ profile -> groups += profile.properties.excludedGroups + "," }
              project.properties.excludedGroups = groups.substring(0, groups.length() - 1)
              ]]>
            </script>
          </scripts>
        </configuration>
      </execution>
    </executions>
  </plugin>
</build>

<profiles>
  <!-- Exclude any tests in `SlowTest` category when profile 'skipSlowTests' is specified. -->
  <profile>
    <id>skipSlowTests</id>
    <properties>
      <excludedGroups>SlowTest.class</activeByDefault>
    </properties>
  </profile>  

  <!-- Skip any tests in 'WindowsTest' category when not running on Windows. -->
  <profile>
    <id>skipWindowsTests</id>
    <activation>
      <os><family>!windows</family></os>
    </activation>
    <properties>
      <excludedGroups>WindowsTest.class</excludedGroups>
    </properties>
  </profile>
</profiles>

现在您可以将${excludedGroups}其用作 surefire 插件配置的值。

于 2017-10-11T21:25:09.803 回答