Documentation for both (Failsafe, Invoker) suggests they are useful for running integration-tests. I cannot figure out which one to use for integration-tests.
Only difference I can see is that Failsafe plugin is specifically designed for running integration-tests, and Invoker plugin just happens to be useful for running integration-tests, but its main purpose is something else. However, when I created a maven-plugin in Eclipse, Maven Invoker Plugin was already included in the POM file, with following code.
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-invoker-plugin</artifactId>
<version>1.7</version>
<configuration>
<debug>true</debug>
<cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo>
<pomIncludes>
<pomInclude>*/pom.xml</pomInclude>
</pomIncludes>
<postBuildHookScript>verify</postBuildHookScript>
<localRepositoryPath>${project.build.directory}/local-repo</localRepositoryPath>
<settingsFile>src/it/settings.xml</settingsFile>
<goals>
<goal>clean</goal>
<goal>test-compile</goal>
</goals>
</configuration>
<executions>
<execution>
<id>integration-test</id>
<goals>
<goal>install</goal>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
What is the main difference between them? Are there specific situations where one should be preferred over other for integration-tests?
The use case is indeed different. You could see the maven-invoker-plugin
as a specific subset of the Failsafe Plugin, intended to be used to test your custom Maven plugins, although its usage can be broader.
The maven-failsafe-plugin
goes hand in hand with the maven-surefire-plugin
(in fact they are all under the surefire
project): it is used to write tests in Java code. The difference between Surefire and Failsafe Plugin is that the first one is used to write unit tests, while the other is used to write integration tests.
An integration test, on the contrary of a unit test, is a test that requires an environment to be present. Environment is a large term, but it encompasses every other tool that the test needs in order to run. For example, if you want to make run a test of your application that depends on the presence of a web server or a database, it is typically an integration test.
Maven integrates this definition in the default
lifecycle by having specific phases in order to set-up the environment needed by the tests, run the tests, and destroy the environement:
The Maven lifecycle has four phases for running integration tests:
pre-integration-test
for setting up the integration test environment.integration-test
for running the integration tests.post-integration-test
for tearing down the integration test environment.verify
for checking the results of the integration tests.
An example is setting up and starting a web server in the pre-integration-test
, testing HTTP calls in the integration-test
and finally stopping the web server in the post-integration-test
.
Do note that the integrations tests in this case are written in Java and sit inside src/test/java
. There is a naming convention to distinguish them from unit tests. So, you're coding the tests.
You are right that its primary use case is not for running integration tests. It was designed in order to invoke other Maven projects during the build. And that specific use-case is very useful when you want to run tests against other Maven projects.
This plugin is in particular handy to perform integration tests for other Maven plugins. The Invoker Plugin can be employed to run a set of test projects that have been designed to assert certain features of the plugin under test.
Let's say you are developing a Maven plugin, and you want to test that it behaves correctly. You can write test with the Surefire Plugin to perform basic testing of its functionality, i.e. features that don't require running your plugin as a whole.
And you could even write integration test with the Failsafe Plugin, which would be tests performing a full run of your plugin against a Maven test project and checking its output. But this would quickly become cumbersome: it would be way easier to create the Maven project on disk using your custom Maven plugin, and let the Invoker Plugin invokes this project. Then you can test that the run behaved correctly.
Overall, to test your Maven plugin, you don't even need to write any Java code: you can just create the test Maven project using your plugin in a directory, let the Invoker Plugin invoke it, and verify that things went right using a post build script written in BeanShell or Groovy. Those are integration tests, in the sense that they required a environment to run (mainly Maven itself), but you didn't really code them.
This is probably why Eclipse generated this for you: you created a Maven Project of packaging maven-plugin
, so it directs you towards the Invoker Plugin to test it.