Testing maven plugins with the verifier approach

Maven is a great build tool that has already proven its benefits. But sometimes, you need an extension for a custom task or need. Luckily, Maven is extensible and allows you to write plugins.

Now, when implementing a Maven plugin, you generally want to test it as well. If possible, we want do do that automatically. Those tests then run on your continuous integration server and you’re notified when, unfortunately, you (or someone else) broke something. Automatic Maven Plugin tests can be done with different approaches. This post focuses on a strategy suitable for integration tests.

Maven Plugin test approaches

There are a lot of ways to test maven plugins as illustrated here. At akquinet, we are interested in integration tests. We developed several plugins and archetypes in the past year, and so were eager to find a way to verify plugin features and detect regressions. One of the requirement was also the possible integration of the strategy in a TDD methodology (Test Driven Development). The ability to quickly reproduce bugs was also an important requirement. So we tried several strategies and decided to use the Verifier approach. It is suitable for all our needs and easy to understand as well as set up.

The verifier approach

Testing plugins with the verifier follows a simple principle:

  1. You create a sample project using your plugin
  2. In your test, you launch Maven on your sample project
  3. Once the execution ends, you check the result (created files, log…)

Obviously, you should define several sample projects and run maven on all of them to check the results. This may appear a bit cumbersome, but we realized this is probably the best way to test maven plugins, as we can tests all features and easily find regressions. To apply the verifier approach, we use the maven-verifier library that manages the Maven launching and supports advanced configurations.

Launching Maven using the maven-verifier

To use the verifier approach, we use the maven-verifier library. Just add the following dependency to the pom file of your test project:

<dependency>
  <groupId>org.apache.maven.shared</groupId>
  <artifactId>maven-verifier</artifactId>
  <version>1.2</version>
</dependency>

Then, in your test, you just need to configure a Verifier object and execute the goal(s):

@Test
public void testMyMojo() throws VerificationException {
  Verifier verifier  = new Verifier(MY_PROJECT.getAbsolutePath() );
  verifier.executeGoal( "package" );
}

The previous code creates a verifier object and sets the root of your sample project. Then it launches mvn package on this project. If the build failed, the executeGoal method throws a VerificationException.

Checking the results

The previous section has shown how we can launch Maven on your project. This section focusses on the after-execution checks. The verifier object has several useful methods to check build result such as:

  • verifyTextInLog: Checks whether the log of the build contains the given text. This can be useful to check the execution of your plugin.
  • verifier.assertArtifactPresent: Checks whether an artifact is you local repository

You can also checks wether expected created files exist by just looking into the target folder of your sample project.

Advanced configuration

The verifier approach is really simple to use but it also offers a lot of interesting settings to help you developing tests.

Configuring your build using system properties

If you want to check several values of a parameter, you don’t have to create several projects. Just pass the value you need as a property.
So your sample pom file should look like:

<configuration>
  <myParameter>${value}</myParameter>
</configuration>

For each value you want to check, just configure the verifier with:

Verifier verifier  = new Verifier( MY_PROJECT.getAbsolutePath() );
Properties props = new Properties(System.getProperties());
props.put("value", "v1");
verifier.setSystemProperties(props);]
verifier.executeGoal( "package" );

The variable value will be replaced by v1. So if you need to check with different values, just change the injected property. You can also use a shortcut:

Properties props = new Properties(System.getProperties());
props.put("value", "v1");
verifier.executeGoal("package", props)

Executing several goals

If you want to execute several goals, you can give a list of goals to the verifier directly:

List<String> goals = new ArrayList<String>();
goals.add("...:...:validate");
goals.add("...:...:generate");
verifier.executeGoals(goals);

Adding parameters in the command line

The verifier also supports command line, and so allows you to configure parameters set from the command line:

verifier.getCliOptions().add("-DmyParameter=v1");
verifier.executeGoal( "package" );

It does not work, can I see the log ?

If you have hard time to understand what’s wrong, you can examine the output of the build. By default, a log.txt is created in your sample project root. You can also configure the log file name using the verifier.setLogFileName(String name) method (useful if you run the verification several times on the same project).

How should my integration-test project look like?

First, create a separated project to test your plugin. Then, create the sample projects within src/test/resources. So for example:

  • src/test/resources/test-default
  • src/test/resources/test-parameter-x

IT Project Structure

When you execute the verifier, use the target/test-classes/your_project location. Indeed, the verifier creates new files (such as the log, artifacts…), and we don’t want to get them into our main code. In addition the mvn clean cleans up all resources created by the verifier.

Conclusion

At akquinet, we have developed several Maven plugins and required a solution to test them properly. We have used the verifier approach for automatic testing of plugins and avoided regressions successfully over the past years. Several of our open source plugins are using this approach, such as the maven-rindirect-plugin and the maven-deploymentpackage-plugin. Testing Maven plugins with the verifier library is very easy, but powerful at the same time. It has also an interesting characteristic: Once a bug is discovered, it is very easy to add a test case that reproduces the bug (just create a failing project) and we can then check this project to ensure it’s fixed. It also fits very well in a TDD process.

The verifier approach can also be used to test archetypes. This will be the topic of another blog post.

One thought on “Testing maven plugins with the verifier approach

  1. Hey there! Quick question that’s totally off topic. Do you know how to make your site mobile friendly? My website looks weird when viewing from my apple iphone. I’m trying to find a template or plugin that might be able to resolve this issue. If you have any suggestions, please share. Appreciate it

Comments are closed.