To use command line to both compile and run integration tests in two peer modules of a multi-module repository following Maven's Standard Directory Layout:
module
|_src
|____it integration-test
|____main
|____test unit-test
update: Turns out, putting IT int tests in the "src / it" folder is not Maven's convention. "src / it" is intended for maven-plugin specific integration tests. Although, "src / it" can certainly be configured for IT int test's - if you need configuration over convention.
I have multi-module repository whose modules are inheriting from parent POMs (project's, and Spring related). I can't compile or run integration tests from command line starting from a "fresh" mvn clean
, but I can get IntelliJ to compile all sources and run all tests (as Maven modules) - after which, int tests will also run at command line despite not having Failsafe bound to phase (sorta makes sense though). I can not pin down what is causing conflict at command line, if anything. Have searched this problem to my capacity's end, and -- yes -- I have tried pretty much every thing I could google, but to no avail. My POMs are defined herein as the current state after all previous attempted changes.
When issuing mvn help:describe -Dcmd=install
on core module, it shows the Failsafe plugin (otherwise defined in my POM) is not being bound to the respective phase(s). This might explain why I can't run integration test, but not why it fails to be bound since it's defined in POM. Also, it does not explain why the int-test source is not compiling, as I am currently understanding int-test compilation to be done by the compiler plugin under the test-compile
phase since there is no int-test-compile
phase in a Maven lifecycle. Is this correct or is this also done in integration-test
phase?
Suppose I mvn clean install
module-parent. Then,
~$: pwd
/repo/module-core
~$: mvn help:describe -Dcmd=install
[INFO] 'install' is a phase corresponding to this plugin:
org.apache.maven.plugins:maven-install-plugin:2.4:install
It is a part of the lifecycle for the POM packaging 'jar'. This lifecycle includes the following phases:
* validate: Not defined
* initialize: Not defined
* generate-sources: Not defined
* process-sources: Not defined
* generate-resources: Not defined
* process-resources: org.apache.maven.plugins:maven-resources-plugin:2.6:resources
* compile: org.apache.maven.plugins:maven-compiler-plugin:3.1:compile
* process-classes: Not defined
* generate-test-sources: Not defined
* process-test-sources: Not defined
* generate-test-resources: Not defined
* process-test-resources: org.apache.maven.plugins:maven-resources-plugin:2.6:testResources
* test-compile: org.apache.maven.plugins:maven-compiler-plugin:3.1:testCompile
* process-test-classes: Not defined
* test: org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test
* prepare-package: Not defined
* package: org.apache.maven.plugins:maven-jar-plugin:2.4:jar
* pre-integration-test: Not defined
* integration-test: Not defined
* post-integration-test: Not defined
* verify: Not defined
* install: org.apache.maven.plugins:maven-install-plugin:2.4:install
* deploy: org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy
MainRepo
|_ module-parent provided below
|____ pom.xml
|
|_ module-core provided below
|____ pom.xml
|
|_ module-backend (spring)
|____ pom.xml
|
|_ module-frontend (angular2)
|____ pom.xml
<project>
<!-- ... -->
<groupId>my.apps.module</groupId>
<artifactId>module-parent</artifactId>
<version>0.1.0</version>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.3.RELEASE</version>
</parent>
<modules>
<module>../module-core</module>
<module>../module-backend</module>
</modules>
<!-- ... -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.20</version>
<executions>
<execution>
<id>module-parent-failsafe-it</id>
<phase>integration-test</phase>
<goals>
<goal>integration-test</goal>
</goals>
</execution>
<execution>
<id>module-parent-failsafe-verify</id>
<phase>verify</phase>
<goals>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
<project>
<!-- ... -->
<groupId>my.apps.module</groupId>
<artifactId>module-core</artifactId>
<version>0.1.0</version>
<parent>
<groupId>my.apps.module</groupId>
<artifactId>module-parent</artifactId>
<version>0.1.0</version>
</parent>
<!-- ... -->
</project>
Also meant to mention I reviewed the effective POM. It looks fine, but I'm not expert in Maven. Spring parent POM || Springs parent's parent POM is correctly setting the Failsafe plugin, so core-module -- I believe -- should be inheriting from that.
I assumed Failsafe not showing up in ..help:describe..
next to respective phases was root of my issue, but it turns out it was not (see answer for failsafe not binding to X or Y ). The setup of two test types (int/unit) between two different source locations (src/it and src/test) was the problem, and it appears to be a common configuration pain when using Maven. This is because it goes against the convention for how Maven assumes a project will be setup.
In order to achieve the use of two different source folders for tests, I found [Kainulainen-2012] who demonstrates the use of [(org.codehaus.mojo:build-helper-maven-plugin)] which configures executions with additional sources for use during compilation. This solves the primary goal as defined above albeit in a non-conventional way while also introducing other problems. Alternatively, using Maven's convention would only require moving Integration tests into the "src/test" location of each module and possibly updating test names. I did not experience additional problems this way, and I found it to be the simpler solution.
mvn install
parent -> core -> backend modulesbuild-helper-maven-plugin
to parent pom.xml under module-parent. mvn install
parent -> core -> backend modules<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>add-integration-test-sources</id>
<phase>generate-test-sources</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>src/it/java</source>
</sources>
</configuration>
</execution>
<execution>
<id>add-integration-test-resources</id>
<phase>generate-test-resources</phase>
<goals>
<goal>add-test-resource</goal>
</goals>
<configuration>
<resources>
<resource>
<filtering>true</filtering>
<directory>src/it/resources</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<!-- ... -->
</plugins>
</build>