Manage surefire plugin test phases in deifferent build environments - testing

I do have a Spring project with integrations tests **IT.java, performance tests **PT.java and ordinary tests. all test are usual tests but testing different functionalities.
in local env during mvn install I would like to skip IT an PT tests (which can be done with skipTests variable).
surefire plugin:
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
<configuration>
<trimStackTrace>false</trimStackTrace>
<classpathDependencyExcludes>
<classpathDependencyExclude>org.liquibase:liquibase-core</classpathDependencyExclude>
</classpathDependencyExcludes>
<excludes>
<exclude>**/*IT</exclude>
<exclude>**/*PT</exclude>
</excludes>
</configuration>
</plugin>
if I add this to skip IT test during mvn install:
<executions>
<execution>
<id>integration-test</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<excludes>
<exclude>none</exclude>
</excludes>
<includes>
<include>**/*IT</include>
</includes>
</configuration>
</execution>
</executions>
it has no impact --> surefire plugin runs test phase (excluding IT and PT test) and automatically runs the integration-test phase where IT tests are included...
How to categorize/group tests to be managable via surefire plugin?
How can I add category/group for PT test - surefire plugin does not have phase for them?
Thank you very much guys.
Iahve tired surefire plugin configuration I found in various already asked questions but nothing solved the problem. especialy if I wnat to categorize/group tests. How do I get my Maven Integration tests to run

Related

Maven build fails with failsafe plugin

I am trying to build my project and run the test by using junit5 and maven failsafe plugin for integration tests.
If I run my test by using
mvn failsafe:integration-test
it runs all the integration tests.
When I run
maven install
failsafe plugin fails with integration tests with error. But surfire plugin works normally. I receive following error for failsafe plugin:
TestEngine with ID 'junit-jupiter' failed to discover tests
...
...
Caused by: java.lang.NoClassDefFoundError: com/mypackage/service/MyObject
My pom with failsafe plugin looks like:
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<useModulePath>false</useModulePath>
<includes>
<include>**/*IT.java</include>
</includes>
<excludes>
<exclude>**/*Test.java</exclude>
</excludes>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
I am using junit jupiter version 5.8.2. I tried to use older versions as it was suggested in other posts but it did not help. Any idea what can be wrong here ?

Cannot skip repackage goal of spring-boot-maven-plugin

I have a multi-module Maven project that contains an application consisting of several Spring Boot services. I am trying to set up integration and end-to-end tests for the services and am using a combination Maven plugins to orchestrate this.
I have one module that is intended to contain only end-to-end tests for groups of collaborating services that perform some work. It contains only test code and resources. I'm using the failsafe plugin (org.apache.maven.plugins:maven-failsafe-plugin) to perform the integration tests, the Spring Boot Maven plugin (org.springframework.boot:spring-boot-maven-plugin) to start and stop the "main" service and the Maven exec plugin (org.codehaus.mojo:exec-maven-plugin) to start the other services that are being used in the end-to-end tests.
I'm running into a problem that appears to be related to the repackage goal of the Spring Boot plugin. The e2e module has nothing that needs to be repackaged, so I want to skip this goal. Shouldn't be too hard, right?
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<skip>true</skip>
</configuration>
<execution>
...
Well, this doesn't work. It runs repackage despite this.
The problem with this, is that the Maven build fails because it can't find a "main" class to repackage (as an executable jar, I believe). Well, there is no main class for this module.
The more important question is: why is <skip>true</skip> being ignored?
You need to add <id>repackage</id> after execution above goals.
I was also facing the same issue. I resolved it by using <pluginManagement> tag above <plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<skip>true</skip>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>

How to wrap an Ant build with Maven?

We use maven for our large-ish product. All of our artifacts are deployed to a shared archiva repository using the maven deploy goal. I am now integrating a third party product that has an ant build. I know how to call ant targets from maven using the antrun plugin, but I'm not sure how to setup the pom in this instance. I don't want maven to actually generate an artifact, but I do want it to pull the artifact that was built by ant when the maven deploy goal is run.
I am planning on having the pom adjacent to build.xml. The pom will use the antrun plugin in the package goal to call the ant target at the appropriate time to build the .war artifact.
Questions:
a) I am creating a .war file but it is created via ant, not Maven, so having a war packaging type in the pom doesn't make sense. What should my packaging type be?
b) How do I cause maven to pull the artifact from my ant output directory for the deploy goal?
c) If there are no good answers to A and B, then are there ant tasks that replicate the maven deploy functionality for getting my .war artifact into the shared repository?
You can use the maven-antrun-plugin to invoke the ant build. Then use the build-helper-maven-plugin to attach the jar produced by ant to the project. The attached artifact will be installed/deployed alongside the pom.
If you specify your project with packaging pom, Maven will not conflict with the ant build.
In the example below, the ant build.xml is assumed to be in src/main/ant, have a compile goal, and output to ant-output.jar.
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>process-resources</phase>
<configuration>
<tasks>
<ant antfile="src/main/ant/build.xml" target="compile"/>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.3</version>
<executions>
<execution>
<id>add-jar</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>${project.build.directory}/ant-output.jar</file>
<type>jar</type>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
You can actually wrap an ANT project with Maven by using multiple ant run goals as I wrote in a different question. Assuming your existing ant project has clean and build tasks, this might be a useful way of wrapping the project so you can use maven goals and have it map to existing ant code.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.3.1</version>
<executions>
<execution>
<id>install-library</id>
<phase>install</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<groupId>x.x</groupId>
<artifactId>ant-out-atifacts</artifactId>
<version>${project.version}</version>
<file>ant-output.jar</file>
<packaging>zip</packaging>
</configuration>
</execution>
</executions>
</plugin>
Refer this: Why you should use the Maven Ant Tasks instead of Maven or Ivy
And specifically, how to invoke a Maven goal from Ant can be found in this example:
http://code.google.com/p/perfbench/source/browse/trunk/perfbench/grails-gorm/build.xml
With the information above you should be able to achieve what you need. Let me know if you have any questions.

How to run individual test in the integration-test target in maven

We have a hundreds of tests defined for our integration-test phase lifecycle in maven, and they take a long time to finish.
What I want to do is run just one test in the integration-test. I tried doing :
mvn -Dtest=<my-test> integration-test
but that does not work. The -Dtest runs only the tests in the unit test goal, not the integration-test phase. I tried the -Dintegration-test=<my-test> instead, and that was ignored.
Is there a way to do that ?
My configuration is:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>surefire-it</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<excludes>
<exclude>none</exclude>
</excludes>
<includes>
<include>**/api/**</include>
</includes>
.....
If you're using the Maven failsafe plugin, you can run a single integration test by setting the it.test property to your fully qualified test class name:
mvn -D it.test=your.TestCase verify
See the failsafe plugin docs for more info.
The Failsafe documentation would have you specify the test like so:
mvn -Dit.test=BrokenIT verify
However, -Dit.test does not appear to work any longer. Rather, the same parameter used to specify a Surefire test will apparently work for Failsafe as well. For example:
mvn -Dtest=WorksIT verify
I've filed a bug (EDIT: which was closed as "Cannot Reproduce" in 2.12) to correct the documentation.
just add -DfailIfNoTests=false works for me with testNG. Something like this:
mvn integration-test -Dtest=aITest -DfailIfNoTests=false
I struggled through this, and I created an additional profile to use when I wanted to run just one integration test. I hope that I've successfully extracted just the right part here:
<profile>
<id>integrationTestSingle</id>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>surefire-it</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<includes>
<include>**/integration/**/${test}.java</include>
</includes>
<skipTests>false</skipTests>
</configuration>
</execution>
</executions>
<configuration>
<argLine>-Xms256M -Xmx768M -XX:MaxPermSize=256M</argLine>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>default-test</id>
<configuration>
<skipTests>true</skipTests>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
Now, I call maven with the integrationTestSingle profile and with -DfailIfNoTests=false -Dtest=NameOfTest, and it doesn't run any of the regular tests during the regular "test" phase, and runs just the NameOfTest test during the integration-test phase.
I'm not sure about JUnit, but for TestNG the strategy would be to define a suite XML file with only the one test, and then in your POM configure the surefire plugin to only run that. In your POM, you would have something like this (disclaimer, this is untested):
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<phase>integration-test</phase>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>single-test.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
To configure the suite file, see http://testng.org/doc/documentation-main.html
Just ran into this myself. Something like this worked well for me:
mvn -Pintegration-test -Dtest=<my-test>
The trick was to ensure that the test-group was mentioned before the -Dtest portion.
I am using:
Apache Maven 3.6.3
openjdk version "11.0.2" 2019-01-15
<groupId>org.codehaus.mojo</groupId>
<artifactId>failsafe-maven-plugin</artifactId>
<version>2.4.3-alpha-1</version>
This command worked for me:
mvn failsafe:integration-test -Dsurefire.skip=true -DskipIntegrationTests=false -DskipTests=false -Dtest=com.myxyz.func.ITestGate
Was actually simpler that the answers above by going back to basics with the actual documentation.
Running Junit 5 integration tests:
openjdk version "11.0.11" 2021-04-20
Apache Maven 3.6.3
In the main build just drop in documented failsafe config:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.0.0-M5</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Then you can run only a specific integration test with:
mvn -Dtest=\*cs1_\* verify
Note that this version will run your tests in the target folder and if you need to load any external files that are something like src\test\resources\x.y then they are copied to target\test-classes\x.y
This works for me, when I gonna run only one test method in integration test
mvn clean -Dit.test=some.package.SomeTestClass#testMethodName integration-test

Maven2 Multiproject Cobertura Reporting Problems During mvn site Build

We've got a multiproject we're trying to run Cobertura test coverage reports on as part of our mvn site build. I can get Cobertura to run on the child projects, but it erroneously reports 0% coverage, even though the reports still highlight the lines of code that were hit by the unit tests.
We are using mvn 2.0.8. I have tried running mvn clean site, mvn clean site:stage and mvn clean package site. I know the tests are running, they show up in the surefire reports (both the txt/xml and site reports). Am I missing something in the configuration? Does Cobertura not work right with multiprojects?
This is in the parent .pom:
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<inherited>true</inherited>
<executions>
<execution>
<id>clean</id>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<inherited>true</inherited>
</plugin>
</plugins>
</reporting>
I've tried running it with and without the following in the child .poms:
<reporting>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
</plugin>
</plugins>
</reporting>
I get this in the output of the build:
...
[INFO] [cobertura:instrument]
[INFO] Cobertura 1.9 - GNU GPL License (NO WARRANTY) - See COPYRIGHT file
Instrumenting 3 files to C:\workspaces\sandbox\CommonJsf\target\generated-classes\cobertura
Cobertura: Saved information on 3 classes.
Instrument time: 186ms
[INFO] Instrumentation was successful.
...
[INFO] Generating "Cobertura Test Coverage" report.
[INFO] Cobertura 1.9 - GNU GPL License (NO WARRANTY) - See COPYRIGHT file
Cobertura: Loaded information on 3 classes.
Report time: 481ms
[INFO] Cobertura Report generation was successful.
And the report looks like this:
I suspect that you're missing an execution of cobertura plugin during the compile phase so that the code only gets instrumented by the reporting plugins, in the site lifecycle, after the tests were run. So the test runs aren't picked up because they run on non-instrumented code. Analyze your build logs more carefully - if I'm right, you'll notice that surefire tests are executed before cobertura:instrument.
My configuration is similar to yours, but in addition to specifying the clean exectution in pluginManagement (like you), I specify the cobertura plugin explicitly in build plugins section:
<build>
...
<plugins>
...
<plugin>
<inherited>true</inherited>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>${cobertura.plugin.version}</version>
</plugin>
</plugins>
</build>
My configuration sorta works, and all Cobertura stuff is in the global organization-wide pom, which all projects use as a parent.
This way projects don't specify anything Cobertura-related in their pom.xml's, but they still generate coverage reports.
I haven't been succesful at getting Cobertura to combine reporting from multi-projects. This has been a problem in general with multi-project reporting.
We have been evaluating sonar as a solution for our metrics reporting. It seems to do a great job of providing summary metrics across projects, including multi-proijects.
The solution implemented by me is somewhat manual, but works. It consists of several steps of one is a step to combine the several .ser files that are generated by Cobertura. This can be done by using the cobertura-merge commandline tool inside a maven task.
According to the output you show is that the files are not actually instrumented, it tells that only 3 files are instrumented.
#Marco is right, it is not possible to achieve this normally through maven only as the maven cobertura plugin is missing a merge goal.
You can achieve it through a mix of maven and ant goals : http://thomassundberg.wordpress.com/2012/02/18/test-coverage-in-a-multi-module-maven-project/
Nevertheless, in the case you have one single project undertest, there is no need to merge. You can, in the test project, copy the .ser file and the instrumented classes from the project under test :
//in test project
<plugin>
<groupId>com.github.goldin</groupId>
<artifactId>copy-maven-plugin</artifactId>
<version>0.2.5</version>
<executions>
<execution>
<id>copy-cobertura-data-from-project-under-test</id>
<phase>compile</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>${project.basedir}/../<project-under-test>/target/cobertura</directory>
<targetPath>${project.basedir}/target/cobertura</targetPath>
<includes>
<include>*.ser</include>
</includes>
</resource>
<resource>
<directory>${project.basedir}/../<project-under-test>/target/generated-classes/cobertura/</directory>
<targetPath>${project.basedir}/target/generated-classes/cobertura</targetPath>
<preservePath>true</preservePath>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
//in parent project
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<configuration>
<format>xml</format>
<aggregate>true</aggregate>
</configuration>
<executions>
<execution>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>${cobertura.version}</version>
</plugin>
</plugins>
</reporting>