How do I execute Junit test case after package phase in maven? - java

I want to run my Junit on my build jar's, but maven surefire plugin executed on class file before package phase that is at test phase, is there any way to run all junit after building a jar of project.
Reason to run on build jar is to verify obfuscation of jar.

Solution is to use the maven-failsafe-plugin which will in the integration test phase. You need to this to your pom file:
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.19.1</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
</project>
You should following the conventions and follow the naming conventions of integration tests:
<includes>
<include>**/IT*.java</include>
<include>**/*IT.java</include>
<include>**/*ITCase.java</include>
</includes>
Afterwards you can run those integration tests via:
mvn clean verify
If you like to run only unit tests:
mvn clean test

There are two phase of tests in maven, one is unit test, second is integration tests. So if You want, You should execute it in integration tests phase.

Related

How to deploy a war via maven before running junit4 integration tests?

I want the maven to deploy war before running the jUnit tests.
I have added the failsafe plugin and a configuration but the deploy is still done after the tests.
Are the tests not run by the failsafe plugin?
<build>
<finalName>testWar</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.16</version>
<configuration>
<systemPropertyVariables>
<wildfly.remote.port>10090</wildfly.remote.port>
</systemPropertyVariables>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.wildfly.plugins</groupId>
<artifactId>wildfly-maven-plugin</artifactId>
<version>1.2.1.Final</version>
<configuration>
<hostname>host</hostname>
<port>10090</port>
<username>user</username>
<password>pw</password>
</configuration>
<executions>
<execution>
<id>wildfly-run</id>
<phase>pre-integration-test</phase>
<goals>
<goal>deploy</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
The behaviour you report suggests that your tests are being run in the test phase instead of the integration-test phase. This is because by default both the Maven Surefire and Maven Failsafe plugins use class name conventions to differentiate between the two types of tests, as described below:
Default Unit Test Behaviour
The Maven Surefire Plugin runs unit tests in the test phase. By default it selects tests to execute based on the class name of the test, as described in Maven Surefire Plugin | Inclusions and Exclusions of Tests:
"**/Test*.java" - includes all of its subdirectories and all Java filenames that start with "Test".
"**/*Test.java" - includes all of its subdirectories and all Java filenames that end with "Test".
"**/*Tests.java" - includes all of its subdirectories and all Java filenames that end with "Tests".
"**/*TestCase.java" - includes all of its subdirectories and all Java filenames that end with "TestCase".
Default Integration Test Behaviour
The Maven Failsafe Plugin runs integration tests tests in the integration-test phase. By default it also selects tests to execute based on the class name of the test, as described in [Maven Failsafe Plugin | Inclusions and Exclusions of Tests](https://maven.apache.org/surefire/maven-failsafe-plugin/examples/inclusion-exclusion.html:
"**/IT*.java" - includes all of its subdirectories and all Java filenames that start with "IT".
"**/*IT.java" - includes all of its subdirectories and all Java filenames that end with "IT".
"**/*ITCase.java" - includes all of its subdirectories and all Java filenames that end with "ITCase".
Therefore you probably just need to rename your integration test classes to conform with one of the three conventions shown above.

Multi-module maven jacoco setup for integration tests

I have maven setup with multiple modules, the setup looks something like this
root module
- domain module
- repository module
- service module
- controllers module
Jacoco is correctly generating test coverage from unit tests and sonar is showing the correct percentage (let's say 20%). Surefire is used for unit tests.
For integration tests its more tricky, we use failsafe and integration tests generate jacoco-it.exec file which is scanned by sonar. My problem is that integration tests are located in the controllers module and it only shows test coverage of integration tests on classes that are inside controllers and not on classes that are in another module like service module. Because of this overall test coverage with integration tests increases to something like 21% instead of 35+%.
Is it possible to configure sonar and jacoco to measure test coverage with the integration tests of all classes instead of classes from same module only, if integration tests are in controllers module?
For reference, this is the relevant setup
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
<sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
...
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.9</version>
<executions>
<execution>
<id>pre-unit-test</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<destFile>${project.build.directory}/jacoco.exec</destFile>
<propertyName>surefireArgLine</propertyName>
</configuration>
</execution>
<execution>
<id>pre-integration-test</id>
<phase>pre-integration-test</phase>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<destFile>${project.build.directory}/jacoco-it.exec</destFile>
<propertyName>failsafeArgLine</propertyName>
</configuration>
</execution>
</executions>
</plugin>
I run my tests with mvn verify and scanner with mvn sonar:sonar
You can aggregate your coverage reports by writing them all to the same destination file.
For example, we're only covering unit tests in our multi-module projects at the moment, so our parent pom contains:
<properties>
...
<sonar.jacoco.reportPath>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPath>
...
</properties>
and
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<configuration>
<destFile>${sonar.jacoco.reportPath}</destFile>
<append>true</append>
</configuration>
<inherited>true</inherited>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
</executions>
</plugin>
This results in a single aggregated report for all modules.
I expect that a similar pattern could be applied to your jacoco IT configuration.

Get correct coverage in sonar for unit and integration tests in separate maven modules

My project setup is simple (all source available at github):
parent
↳ backend
↳ client
↳ integration-tests
And after runing maven:
mci sonar:sonar -Dsonar.host.url=http://localhost:9000 -Dsonar.login=12...9
I see that unit and integration tests are visible for sonar, but coverage from IT is not.
For Intelij IDEA jacoco-it.exec looks fine:
I'm assuming that culprit is here:
[INFO] Sensor JaCoCoSensor [java]
[INFO] No JaCoCo analysis of project coverage can be done since there is no class files.
[INFO] Sensor JaCoCoSensor [java] (done) | time=1ms
So I did small hack (in short: copied all source files to integration-test module):
<properties>
<sonar.sources>${basedir}/target/copied</sonar.sources>
</properties>
[...]
<!-- hack to generate coverage reports -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>${maven-resources-plugin.version}</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>generate-sources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${sonar.sources}</outputDirectory>
<resources>
<resource>
<directory>${basedir}/../backend/src/main/java</directory>
<filtering>false</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${sonar.sources}</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
But now all my classes ale duplicated (sonar shows also classes from ../target/copied dir):
Sonar version: 6.5
Jacoco maven plugin: 0.7.5.201505241946 (also tried lastest 0.7.9)
Any ideas what should I do here?
Looks like I have answer for that question:
Report wasn't generated because post-unit-test execution was in the wrong phase. Instead of <phase>test</phase> I now have <phase>verify</phase>
I had a wrong goal for post-integration-test. The change was from <goal>report-integration</goal> to <goal>report-aggregate</goal>:
This goal allows me to create coverage reports when tests are in separate projects from the code under test.
Added properties:
<jacoco.itReportPath>${project.basedir}/../integrations-tests/target/jacoco-it.exec</jacoco.itReportPath> and
<sonar.jacoco.reportPaths>${jacoco.itReportPath},${project.build.directory}/jacoco-it.exec,${project.build.directory}/jacoco.exec</sonar.jacoco.reportPaths>
All those chages and update project available on github
I use mainly jacoco for coverage. You need to have a few things in place before you start
Enable and configure surefire plugin
Enable and configure the jacoco plugin
It's a one time configuration that you will build and forget, one of my projects serving as parent enables this feature. Feel free to check it out:
https://github.com/slixes/parent/blob/master/pom.xml

How to get unit tests to run in Maven Tycho build?

I've done a lot of work in the past writing unit tests that run in "conventional" Maven builds,
using JUnit and Mockito (and PowerMock). I'm now working on an Eclipse plugin codebase, which builds with Maven Tycho.
Overall, it's a multiproject build, but I'm only adding unit tests to one of the plugin projects (for now).
I've heard of tycho-surefire, but that seems pretty complicated, and it really sounds more like it supports integration tests instead of unit tests. I'm guessing I'll probably have no choice but to use this, but so far I haven't tried to integrate it.
I tried getting the JUnit and Mockito artifacts from Maven, and then using the maven-dependency-plugin to get the artifacts available to be referenced in the Bundle-Classpath property of the manifest.
When I run the build, the tycho-compiler-plugin I see it compiling 105 source files, which includes all of the classes in src/main/java and src/test/java.
It fails to compile the test class because it can't find the Mockito classes, even though when I run the build with -X, it shows the mockito-all artifact in the dependency tree.
What can I do here?
After a lot of painful Maven trial & error I struggled across this website, which provides a surprisingly easy way to use unit-tests in a Maven-Tycho setup.
Here, the important parts of the pom.xml when using JUnit (probably looks similar for Mockito):
<testSourceDirectory>src/test/java</testSourceDirectory>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.4</version>
<executions>
<execution>
<id>test</id>
<phase>test</phase>
<configuration>
<includes>
<include>**/*Test.java</include>
</includes>
</configuration>
<goals>
<goal>test</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<executions>
<execution>
<id>compiletests</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
Name all your tests in a way so that they end with *Test.java. Run mvn test in order to execute all available unit-tests.
You have to use junit and Mockito as osgi bundles
I think this Question answered detailed here
I hope this helps.

Maven 3 JavaDoc Plugin Conflicts with TestNG Groups

I have the following:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>${maven-javadoc-plugin.version}</version>
<executions>
<execution>
<id>javadoc-jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
Which works fine during packaging or installing:
mvn install or mvn package, however, as soon as I try to specify a TestNG Group to run for the tests:
mvn install -Dgroups=somegroup
it fails with the following error after tests finish running:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-javadoc-plugin:2.9.1:jar (javadoc-jar)
on project ibd.database.api: Unable to parse configuration of mojo
org.apache.maven.plugins:maven-javadoc-plugin:2.9.1:jar for parameter
#: Cannot find default setter in class org.apache.maven.plugin.javadoc.options.Group
Thanks for any info or guidance on this.
The problem is that both the surefire and javadoc plugins use the -Dgroups parameter, and in your case the javadoc plugin cannot find the "somegroup".
As far as I know there is no clean solution for this, but you can do a workaround by defining a custom property in your pom.xml:
<properties>
<surefire.groups></surefire.groups>
</properties>
Then use the property in the surefire configuration:
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
...
<configuration>
<groups>${surefire.groups}</groups>
</configuration>
</plugin>
Now you can run the tests from command line using the surefire.groups property:
mvn install -Dsurefire.groups=somegroup

Categories