Cookbook: How To Use Maven Plugin Testing Harness?

This guide is intended as a reference for those developing Maven plugins, with self-contained references and solutions for common testing cases.

Prerequisites

We assume that you have already created a plugin. In this cookbook, we make reference to MyMojo in maven-my-plugin which is generated by the Maven Archetype Plugin, i.e.:

mvn archetype:create \
  -DgroupId=org.apache.maven.plugin.my \
  -DartifactId=maven-my-plugin \
  -DarchetypeArtifactId=maven-archetype-mojo

The generated structure should be:

maven-my-plugin
  |- pom.xml
  +- src/
   +- main/
      +- java/
        +- org/
          +- apache/
            +- maven/
              +- plugin/
                +- my/
                  |- MyMojo.java

Recipe

Add maven-plugin-testing-harness dependency

As usual, just add maven-plugin-testing-harness as following in your pom. Be sure to specify test scope.

<project>
  ...
  <dependencies>
    <dependency>
      <groupId>org.apache.maven.plugin-testing</groupId>
      <artifactId>maven-plugin-testing-harness</artifactId>
      <scope>test</scope>
    </dependency>
    ...
  </dependencies>
  ...
</project>

Create a MyMojoTest

Create a MyMojoTest (by convention) class in src/test/java/org/apache/maven/plugin/my directory. This class should extend AbstractMojoTestCase from maven-plugin-testing-harness.

public class MyMojoTest
    extends AbstractMojoTestCase
{
    /** {@inheritDoc} */
    protected void setUp()
        throws Exception
    {
        // required
        super.setUp();

        ...
    }

    /** {@inheritDoc} */
    protected void tearDown()
        throws Exception
    {
        // required
        super.tearDown();

        ...
    }

    /**
     * @throws Exception if any
     */
    public void testSomething()
        throws Exception
    {
        File pom = getTestFile( "src/test/resources/unit/project-to-test/pom.xml" );
        assertNotNull( pom );
        assertTrue( pom.exists() );

        MyMojo myMojo = (MyMojo) lookupMojo( "touch", pom );
        assertNotNull( myMojo );
        myMojo.execute();

        ...
    }
}

In this case, testSomething() will test MyMojo against a Maven project called project-to-test.

Note: By convention, Mojo unit tests should be in the test resources directory.

Configuring project-to-test pom

Just create a pom as usual. The names for groupId and artifactId don't really matter since this project will not be deployed.

<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.apache.maven.plugin.my.unit</groupId>
  <artifactId>project-to-test</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>
  <name>Test MyMojo</name>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <artifactId>maven-my-plugin</artifactId>
        <configuration>
          <!-- Specify the MyMojo parameter -->
          <outputDirectory>target/test-harness/project-to-test</outputDirectory>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

Execute test

As usual, just call:

mvn test