结合Maven中的配置文件跳过多类单元测试?

时间:2013-11-07 01:04:26

标签: unit-testing maven maven-profiles

我在尝试将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测试,我可以在非Windows操作系统上执行mvn test(或在命令行中明确指定-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上添加一个依赖项,以便在测试期间加载SlowTestWindowsTest接口。我已将maven-surefire-plugin放在我父POM的pluginManagement部分中,但为此插件定义的任何依赖项都不能包含test范围。因此,在定义SlowTestWindowsTest接口的模块外部运行测试将不起作用。我可以在配置文件中为插件添加test范围依赖关系,但这不包括没有配置文件处于活动状态的情况。

2 个答案:

答案 0 :(得分:1)

您可以使默认配置文件排除所有组,并为每个配置文件添加failafe / surefire插件的一次执行,仅包括一个组。

答案 1 :(得分: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插件配置的值。