does maven profile configured for integration phase execute during build life cycle? - maven

Here is the condensed snippet of pom.xml from my project
<profiles>
<profile>
<id>run-tests</id>
<build>
<plugins>
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>replacer</artifactId>
<version>1.5.2</version>
<executions>
<execution>
<phase>pre-integration-test</phase>
<goals>
<goal>replace</goal>
</goals>
</execution>
</executions>
<configuration>
<includes>
......
</includes>
<replacements>
<replacement>
.......
</replacement>
</replacements>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.18.1</version>
<configuration>
......
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<phase>integration-test</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
I have two questions:
1) when I execute mvn clean package -Prun-tests, what happens? I expected none of these plugin goals to execute here because they are bound to integration-test phase. But I see these goals executed why?
2) what does having two goals in execution block mean? please see above in failsafe-plugin
Thanks

A partial answer:
1) No Way. Unless you also have these plugins configured in the main build section to be run in phases up to package.
How did you determine that the plugins had run? Do you have something such as the following in the maven output?
[INFO] --- maven-failsafe-plugin:2.18.1:integration-test (default)
[INFO] --- maven-failsafe-plugin:2.18.1:verify (default)
2) That means that the two goals (mojos) will be executed in the integration-test phase. First the integration-test goal, immediately followed by the verify goal.
Comment: integration-test goal is by default bound to the integration-test phase, whereas the verify goal is bound to the verify phase. So you could have configured the failsafe plugin this way:
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
Note that the phase is ommited

Related

Maven failsafe is not complaining that an inexistent profile was specified

I have two profiles in my pom:
<profiles>
<profile>
<id>functional-tests</id>
<build>
<plugins>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<testSourceDirectory>test/test-functional/java</testSourceDirectory>
<includes>
<include>**/*FT.java</include>
</includes>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>it-tests</id>
<build>
<plugins>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<testSourceDirectory>test/test-it/java</testSourceDirectory>
<includes>
<include>**/*IT.java</include>
</includes>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
...
I can trigger each of these two profiles like this:
mvn failsafe:integration-test -Pfunctional-tests
mvn failsafe:integration-test -Pit-tests
But when I run this:
mvn failsafe:integration-test -PrandomWord
It triggers it-tests profile. I was wondering why and if there is a way to have failsafe plugin output something like unrecognised profile.
Thank you for your help
In case it matters, here is my failsafe-plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
</goals>
</execution>
</executions>
</plugin>
Answering your question about why it triggers it-tests. In fact, it does not activate any of the profiles, hence default plugin configuration is used which has **/*IT.java in include list. So, it runs all IT tests by default.
This is weird approach to manage plugin executions by profiles. I doubt there is a reasonable way to validate profile names as you describe. I would recommend another approach here.
Approach 1. Use <id> and cli with #
You could just specify two executions of the plugin with id and then you could do this: How to execute maven plugin execution directly from command line?
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<id>it-tests</id>
<phase>none</phase> <!-- detach this execution from default lifecycle -->
<configuration>
<testSourceDirectory>test/test-it/java</testSourceDirectory>
<includes>
<include>**/*IT.java</include>
</includes>
</configuration>
</execution>
<execution>
<id>functional-tests</id>
<phase>none</phase> <!-- detach this execution from default lifecycle -->
<configuration>
<testSourceDirectory>test/test-ft/java</testSourceDirectory>
<includes>
<include>**/*FT.java</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
Now you could execute it from command line:
mvn failsafe:integration-test#it-tests
mvn failsafe:integration-test#functional-tests
Update: No need to specify goals as it is relevant to lifecycle only, we type it in command line anyway.
Approach 2. Use <skip> and properties
Keep both executions as a part of lifecycle but control execution by providing skip flags. I.e. define two properties e.g. skip.tests.it=true, skip.tests.ft=true and add <skip>${skip.tests.ft}</skip> to relevant configuration sections. Then you could just do
# run with no tests by default
mvn verify
# run with only FT
mvn verify -Dskip.tests.ft=false
# run with all tests
mvn verify -Dskip.tests.ft=false -Dskip.tests.it=false
to run full lifecycle together with desired tests.

Maven Config Plugins running twice

I have the following pom config. I added the cobertura plugin, and now pmd, cpd, findbugs, and test are running twice.
I understand that is because of my "phases" config, but I don't understand how can I achieve the following:
What I want is before I commit to the repo, build my app and check for pmd errors, findbugs errors, check my tests, and check my cobertura.
How can I achieve this? I am used to run "mvn clean package" before commit. It's that ok?
Here's my config:
...
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<version>3.8</version>
<configuration>
<linkXref>false</linkXref>
<rulesets>
<!-- Custom Ruleset -->
<ruleset>codequality/pmd.xml</ruleset>
</rulesets>
</configuration>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>pmd</goal>
<goal>cpd</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>3.0.4</version>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>2.7</version>
<configuration>
<check>
<haltOnFailure>true</haltOnFailure>
<branchRate>70</branchRate>
<lineRate>70</lineRate>
<totalBranchRate>70</totalBranchRate>
<totalLineRate>70</totalLineRate>
<packageLineRate>70</packageLineRate>
<packageBranchRate>70</packageBranchRate>
</check>
</configuration>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>clean</goal>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Any maven plugin has a default execution phase. In this case, the plugins that you apply are executed in the verify phase (pmd-plugin). But you are defining it to run also in the compile phase. Removes the phase tag and lets it run in the verification phase.
<execution>
<!--<phase>compile</phase>-->
<goals>
<goal>...</goal>
...
</goals>
</execution>
Finally, the good practice to validate your project before a commit is to run:
mvn clean verify

Is isolation of failsafe and surefire runs from each other using a skip approach possible?

The value of property skipITs when overridden on the command line appears to be ignored by maven if used in conjunction with -Dit.test=full.Classname. The specified failsafe test will not be run (case one).
As opposed to this specifiing skipITs without the it.test switch leads to running of existing failsafe tests (case two).
Background: Am trying to isolate surefire tests from failsafe tests runs by namely either running both types of them or one of each only. The maven calls are:
mvn -Pintegration -DskipTests=true -DskipITs=false -Dit.test=full.Classname verify
in the first case and:
mvn -Pintegration -DskipTests=true -DskipITs=false verify
in the second.
The relevant configuration (pom.xml, snippets only) being:
<properties>
<skipTests>false</skipTests>
<skipITs>false</skipITs>
</properties>
(those are defaults) and
<profiles>
<profile>
<id>integration</id>
<build>
<plugins>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<id>custom<id>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<skipTests>${skipITs}</skipTests>
<skip>${skipITs}</skip>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
Did you observe that too or have you eventually found a better working approach?
By default, the Surefire plugins runs during the test phase and usually you configure the Failsafe plugin to run during the integration-test and verify phase like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.18.1</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
To run the Surefire tests only, use
mvn clean test
To run both the Surefire and the Failsafe tests, use
mvn clean verify
You can completely skip any plugin by using the <skip> configuration option. If you configure the Surefire plugin like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<skip>${skip.surefire}</skip>
</configuration>
</plugin>
you can run only the Failsafe tests by calling
mvn clean verify -Dskip.surefire=true
If the integration test (it.test) has a non-default name I need to add an include pattern accordingly, like in (pom.xml snippet):
<profiles>
<profile>
<id>dbUnit</id>
<build>
<plugins>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<id>custom</id>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<skipTests>${skipITs}</skipTests>
<skip>${skipITs}</skip>
<includes>
<include>**/*DbTest.java</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
But that appears valid only for the original approach. Also observe that the default inclusion patterns might need to be added too in case for your integration tests you followed different naming schemes.

why list the goals of a plugin without binding to a phase?

Please consider this pom excerpt taken from jacoco example ( http://www.eclemma.org/jacoco/trunk/doc/examples/build/pom-it.xml)
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.5-SNAPSHOT</version>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>default-prepare-agent-integration</id>
<goals>
<goal>prepare-agent-integration</goal>
</goals>
</execution>
<execution>
<id>default-report</id>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>default-report-integration</id>
<goals>
<goal>report-integration</goal>
</goals>
</execution>
<execution>
<id>default-check</id>
<goals>
<goal>check</goal>
</goals>
<configuration>
<rules>
<!-- implmentation is needed only for Maven 2 -->
<rule implementation="org.jacoco.maven.RuleConfiguration">
<element>BUNDLE</element>
<limits>
<!-- implmentation is needed only for Maven 2 -->
<limit implementation="org.jacoco.report.check.Limit">
<counter>COMPLEXITY</counter>
<value>COVEREDRATIO</value>
<minimum>0.60</minimum>
</limit>
</limits>
</rule>
</rules>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.16</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.16</version>
<executions>
<execution>
<id>default-integration-test</id>
<goals>
<goal>integration-test</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
Now I know that you can bind a plugin's goal to a maven phase, that is run that goal when maven executes a specific phase.
What is the point of just listing the integration-test goal for the maven failsafe plugin without binding it to something?
The same as for jacoco report and others goal? I don't think you can force the plugin to execute just those listed goals right?
Many thanks
The point is that a plugin can define default life cycle phases where the appropriate goal is bound to (many plugins do this). In this cases you don't need to specify the life cycle phase within the pom file explicitly.
For example the maven-failsafe-plugin has a goal integration-test. This goal has a default binding to the integration-test life cycle phase. Here an excerpt from the documentation:
Description:
Run integration tests using Surefire. Attributes:
Requires a Maven project to be executed.
Requires dependency resolution of artifacts in scope: test.
The goal is thread-safe and supports parallel builds.
Binds by default to the lifecycle phase: integration-test.
That's the reason why you don't need to give a life cylce phase in the configuration like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.18.1</version>
<executions>
<execution>
<id>default-integration-test</id>
<goals>
<goal>integration-test</goal>
</goals>
</execution>
</executions>
</plugin>
The same is meant for the jacoco maven plugin.
If I understand correctly, M2E will execute the plugin goal during workspace full or incremental builds.
The following article may shed some light:
http://eclipse.org/m2e/documentation/m2e-execution-not-covered.html
You are correct that, on command line, you would not be able to specify the goal, since it is a plugin goal and not tied to a phase. This could be an oddball usage specifically for M2E integration.

maven-failsafe-plugin is not executing my integration tests

Bellow a part of my actual pom.
Testng tests for integration tests have been assigned a "integration" group in the #Test annotations.
To do little test I did not exclude the "integration" group during the test phase.
When building using for example mvn verify or mvn install the integration tests get executed in the test phase, but not the verify or integration-test phase.
The number of tests run remains 0. Somehow they are not picked up. Anyone have an idea on what might be wrong?
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.1</version>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.12.1</version>
<executions>
<execution>
<id>integration-test</id>
<phase>integration-test</phase>
<goals>
<goal>integration-test</goal>
</goals>
<configuration>
<skip>false</skip>
<excludedGroups>unit</excludedGroups>
</configuration>
</execution>
<execution>
<id>verify</id>
<phase>verify</phase>
<goals>
<goal>verify</goal>
</goals>
<configuration>
<skip>false</skip>
<excludedGroups>unit</excludedGroups>
</configuration>
</execution>
</executions>
<configuration>
<skip>false</skip>
<excludedGroups>unit</excludedGroups>
</configuration>
</plugin>
Update: Adding TestNG as a dependency to the failsafe plugin does not
help
maven-failsafe-plugin by default includes only files matching following patterns:
<includes>
<include>**/IT*.java</include>
<include>**/*IT.java</include>
<include>**/*ITCase.java</include>
</includes>
How did you name your test class(es)?

Resources