Search code examples
mavenmaven-failsafe-plugin

How to skip failsafe execution for pom packaging?


I wanted to configure failsafe with failIfNoTests in a parent pom because we are currently upgrading Spring Boot in our microservices, and tests might not be properly detected if they are still using JUnit 4 (you need to migrate them or use junit-vintage).

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <configuration>
                    <failIfNoTests>true</failIfNoTests>
                </configuration>
            </plugin>

The problem however is that this causes the plugin to also run in the build of the parent pom. I don’t want to put this in <pluginManagement> because I want to make sure that the plugin is running in child projects (otherwise they still have to declare the plugin and it might be forgotten).

Is there a way to prevent the failsafe plugin from running with pom packaging?

Note that I did the same with surefire, but there is no issue with that one as its goals are managed by Maven’s default lifecycle, which depends on the pom packaging. However for failsafe the goals are declared in spring-boot-starter-parent’s <pluginManagement> so it applies for all packaging types.

For the moment, I did it with a profile based on this question, but I find this quite dirty:

        <profile>
            <id>disable-integration-tests-for-pom-packaging</id>
            <!-- this profile detects that we are not building an artifact, so we shouldn’t run failsafe -->
            <activation>
                <file>
                    <!-- can’t rely on ${project.*} for profile activation -->
                    <missing>${basedir}/src</missing>
                </file>
            </activation>
            <properties>
                <skipITs>true</skipITs>
            </properties>
        </profile>

Full poms

Parent:

<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <!-- if changed, update spring-boot.version too! -->
        <version>2.6.6</version>
        <relativePath />
    </parent>

    <groupId>org.example</groupId>
    <artifactId>parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <configuration>
                    <failIfNoTests>true</failIfNoTests>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

mvn verify output:

[INFO] Scanning for projects...
[INFO] 
[INFO] -------------------------< org.example:parent >-------------------------
[INFO] Building parent 1.0-SNAPSHOT
[INFO] --------------------------------[ pom ]---------------------------------
[INFO] 
[INFO] --- maven-failsafe-plugin:2.22.2:integration-test (default) @ parent ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  0.619 s
[INFO] Finished at: 2022-04-14T14:07:56+02:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-failsafe-plugin:2.22.2:integration-test (default) on project parent: No tests to run! -> [Help 1]

microservice 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">
    <parent>
        <artifactId>parent</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
        <!-- just to be able to build since I can’t actually install the parent -->
        <relativePath>../parent</relativePath>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>microservice</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

Build should succeed as long as there are integration tests (and of course all of them are succeeding).


Solution

  • If you want a plugin to not run in the parent, but run in the child, you can add something along the following in the <plugins> section of your parent POM:

          <plugin>
            <artifactId>maven-source-plugin</artifactId>
            <executions>
              <execution>
                <id>attach-sources</id>
                <inherited>false</inherited>
                <phase>none</phase>
              </execution>
            </executions>
          </plugin>
    

    This is for the maven source plugin, but you can adapt it for the failsafe plugin as well.