Maven profiles are not inherited in child modules - java

I'm trying to separate different kinds of tests (unit, integration, acceptance) by using maven profiles. This is the part of the main pom file:
<properties>
<build.profile.id>dev</build.profile.id>
<skip.unit.tests>false</skip.unit.tests>
<skip.integration.tests>true</skip.integration.tests>
<skip.acceptance.tests>true</skip.acceptance.tests>
</properties>
<profiles>
<profile>
<id>dev</id>
</profile>
<profile>
<id>integration-test</id>
<properties>
<build.profile.id>integration-test</build.profile.id>
<skip.unit.tests>true</skip.unit.tests>
<skip.integration.tests>false</skip.integration.tests>
<skip.acceptance.tests>true</skip.acceptance.tests>
</properties>
</profile>
<profile>
<id>acceptance-test</id>
<properties>
<build.profile.id>acceptance-test</build.profile.id>
<skip.unit.tests>true</skip.unit.tests>
<skip.integration.tests>true</skip.integration.tests>
<skip.acceptance.tests>false</skip.acceptance.tests>
</properties>
</profile>
</profiles>
<build>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.17</version>
<configuration>
<skipTests>${skip.unit.tests}</skipTests>
<includes>
<include>**/*UnitTests.java</include>
</includes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.17</version>
<executions>
<execution>
<id>integration-tests</id>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<skipTests>${skip.integration.tests}</skipTests>
<includes>
<include>**/*IntegrationTests.java</include>
</includes>
</configuration>
</execution>
<execution>
<id>acceptance-tests</id>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<skipTests>${skip.acceptance.tests}</skipTests>
<includes>
<include>**/*AcceptanceTests.java</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
As you can see I'm using the profile information to run certain types of tests based on the profile that is used. Default profile is dev and it will only run unit tests. They can be executed like this:
mvn clean test
For integration and acceptance tests I use failsafe plugin: Example of running integartion tests would be:
mvn clean verify -P integration-test
This works fine when I run it from the main pom module, but it doesn't work when running it from the child module. Tests are just ignored. Looking at the effective pom for child module I don't see the profiles. Am I doing something wrong or is this is expected behavior from maven? If profile inheritance (needs to cascade to deepest modules in the hierarchy) can't be achieved this way how can it be done?
Update: This is the project hierarchy
project directory
--main module
--commons module
--administration
----domain
----data
----business
----web

With multimodule project you usually don't execute modules directly. Instead you should always execute the main module, but specify only your desired submodule via -pl parameter. There are a lot more issues connected with running modules directly.
Just double checked some multi-module projects I have participated on and I we are using <pluginManagement> to propagate plugin configuration form parent POM to child projects.

Related

How to prevent Maven Surefire from running Spring integration tests automatically

My integration tests take long to run, and I don't want my developers to waste time every time they need to compile. I only want my integration tests to run:
In my CI/CD server.
When I tell my IDE (NetBeans) to specifically run a test file.
Is this possible? How can I achieve it?
Add a configuration to your POM that excludes the integration tests during your normal build (assuming that your integration tests are named something like UserService_IT.java.
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>${skip.surefire.tests}</skipTests>
<excludes>
<exclude>**/*_IT*.java</exclude>
</excludes>
</configuration>
To run the integration tests, say in your CI build, add a profile and activate it in your pipeline, like mvn verify -Pintegration-tests.
<profile>
<id>integration-tests</id>
<activation>
<activeByDefault>false</activeByDefault>
<property>
<name>integration-tests</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<includes>
<include>**/*_IT.java</include>
</includes>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>

Overriding property in maven archetype integration test

I'm generating a project from an archetype and I have a property in pom of this generated project (archetype-resources/pom):
<properties>
<myProperty>productionValue</myProperty>
</properties>
and the following surefire configuration:
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<argLine>
-Djava.library.path=${myProperty}
</argLine>
</configuration>
</plugin>
I want myProperty to be overridden with value from my archetype pom when I run ITs and stay the same when users generate this project. How do I do that?
I tried setting it in archetype.properties file, but it has a variable in it:
myProperty=${project.basedir}/IT/path.
I want ${project.basedir} to be a basedir of archetype project in case of ITs, not of generated project, which is not the case when I do it like that.
Another way I tried is to use plugin configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-archetype-plugin</artifactId>
<version>${maven-archetype.version}</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
</goals>
<configuration>
<properties>
<myProperty>${project.basedir}/IT/path</myProperty>
</properties>
</configuration>
</execution>
</executions>
</plugin>
But it didn't work as well, myProperty in pom of generated project is not changed. What is it that I'm doing wrong? Thank you so much for your help!
The problem was that I have put
<configuration>
<properties>
<myProperty>${project.basedir}/IT/path</myProperty>
</properties>
</configuration>
under <execution> tag and not <plugin>. After I did that it worked as expected.

Cannot run multiple executions in maven surefire?

I want to run test classes whose name end with ResourceTest.java, so I defined following execution.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</configuration>
<version>2.12.2</version>
<executions>
<execution>
<id>resource-tests</id>
<phase>resource-tests</phase>
<goals>
<goal>resource-tests</goal>
</goals>
<configuration>
<includes>**/*ResourceTest.java</includes>
<!-- <exludes>**/*.java</exludes> -->
</configuration>
</execution>
</executions>
</plugin>
But I'm not sure how to run this, I've searched a lot and I'm missing something.
I tried surefire:test, it skipped all the test cases as defined in above configuration. So, I tried surefire:resource-tests, maven is saying no goal is not defined.
I'm using eclipse to run my maven build, by passing these parameters. How can I run by the execution id?
How to select a specific execution when running with surefire:test when I've mulltiple executions defined in my pom?
What am I missing? Any help would be appreciated.
There are several problems with your current configuration :
you are forcing the maven-surefire-plugin to be executed in the resource-tests phase but this phase does not exist. You should delete that declaration to keep the default plugin binding phase, which is test.
you are invoking the goal resource-tests but maven-surefire-plugin does not define such a goal.
the <includes> element is ill-defined. There should be a <include> tag under it.
you are excluding all Java files from the plugin configuration so no test will be run
the configuration of the plugin should be done under the <configuration> element not for each <executions>.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.2</version>
<configuration>
<includes>
<include>**/*ResourceTest.java</include>
</includes>
</configuration>
</plugin>
When you have multiple executions and you want "select" one of them, you can use a profile:
<profiles>
<profile>
<id>resource-tests</id>
<properties>
<test-classes>**/*ResourceTest.java</test-classes>
</properties>
</profile>
<profile>
<id>task-tests</id>
<properties>
<test-classes>**/*TaskTest.java</test-classes>
</properties>
</profile>
</profiles>
with the following plugin configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.2</version>
<configuration>
<includes>
<include>${test-classes}</include>
</includes>
</configuration>
</plugin>
With such a configuration:
when you run mvn clean test -Presource-tests, only the classes matching **/*ResourceTest.java will be tested
when you run mvn clean test -Ptask-tests, only the classes matching **/*TaskTest.java will be tested

Maven changes the order of plugins of different profiles

I have a pom.xml where I define the same plugin (same groupId and artifactId, different execution :-) ) in two different profiles. The executions are defined in the same phase, so the order is calculated by the order from the xml:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<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>echo</groupId>
<artifactId>test</artifactId>
<name>echo-test</name>
<version>1.0.0</version>
<packaging>pom</packaging>
<profiles>
<profile>
<id>1st-profile</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>1st-antrun-echo</id>
<phase>test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<echo>1st antrun plugin</echo>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>2nd-profile</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>com.soebes.maven.plugins</groupId>
<artifactId>maven-echo-plugin</artifactId>
<version>0.1</version>
<executions>
<execution>
<id>1st-soebes-echo</id>
<phase>test</phase>
<goals>
<goal>echo</goal>
</goals>
<configuration>
<echos>
<echo>1st echo-plugin</echo>
</echos>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>2nd-antrun-echo</id>
<phase>test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<echo>2nd antrun plugin</echo>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
All the plugin executions are defined in the test phase, therefore I would expect the following order:
1st antrun plugin
1st echo-plugin
2nd antrun plugin
However, since the antrun-plugins are merged, I get this output:
1st echo-plugin
1st antrun plugin
2nd antrun plugin
This command explains why is this happening: mvn help:effective-pom
Is there any other solution to preserve the order other than to introduce a new phases? Our project is really big and this is a very simplified example.
Why is this limitation of maven to merge the plugins into one with multiple executions?
In my experience this is one of the biggest bugs in Maven. If you have more than one configuration for the same plugin in different profiles, the order is simply unpredictable. I even observed, that I had some plugin order in project B in a given phase, and as soon as some of the same plugins got a config in a parent project (not even in the same phase), the order was ruined.
There is an obviously falsely closed bug related to this at https://issues.apache.org/jira/browse/MNG-2258.
Possible workarounds
Try to shift some of the plugins to previous phase if possible
(prepare-test used for some of the plugins and test for the rest)
Try
to replace the functionality of multiple plugins with a
groovy-maven-plugin script (quite handy with the ant integration, and
you reach the list of the active profiles in the script)
Write your
own mojo and call the plugins in the correct order (See
https://github.com/TimMoore/mojo-executor)
Give a try to gradle. Maybe it fits your needs, and it comes with a lot of good things from Maven
I do not think that there is any more you can do right now.

maven multiple test suits in surefire plugin

I am using TestNg and Maven with the surefire plugin to run my tests. I have several different tests that I want to run in the same pom. Currently to do this I have two different XML files defined and i've defined two profiles to run different xml files but this keeps throwing errors!
I don't know how I should solve this issue.
Any help will be greatly appreciated!
<profile>
<id>run</id>
<activation>
<property>
<name>start</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
<suiteXmlFiles>
<suiteXmlFile>${project.build.directory}/resources/testng.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
<executions>
<execution>
<id>test</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<skip>false</skip>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
Imagine profile 2 to be pretty much the same BUT the xml suite file is different
I get a parsing error: It can't find the test class in the suiteXmlFile. However, if I just use one profile have just one xml file, it's acceptable. The one that was failing also works.
Try to move suiteXmlFiles to execution configuration and use maven-failsafe-plugin that is more suitable for integration tests

Categories

Resources