Surefire wont trigger the integration tests - maven

I am facing this issue in my Spring MVC project:
I have two types of tests. Unit and Integration. Both separated by package in test/java, respectively by test/java/unit and test/java/integration. I am using maven-surefire plugin to trigger tests.
I have two profiles, unit and integration defined in pom.xml
<profile>
<id>unit</id>
<properties>
<include.tests>**/unit/**/*.java</include.tests>
</properties>
</profile>
<profile>
<id>integration</id>
<properties>
<include.tests>**/integration/**/*.java</include.tests>
... other properties for configuring integration platform (DB, ...) omitted for simplicity
</properties>
</profile>
And surefire plugin is configured like this
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<includes>
<include>${include.tests}</include>
</includes>
</configuration>
</plugin>
When I run mvn surefire:test -Punit, all unit tests are triggered, which is what I want (I´ve checked the amount of tests passed is same as amount of tests passed when I trigger them by unit folder for example from IDEA).
But when I try to run mvn surefire:test -Pintegration, the task will run and "succeed", but the number of tests peformed is 0. But when I run these tests from IDEA for example with Integration profile active, I see there is X tests which will run successfully.
Basic integration tests uses #RunWith(SpringJUnit4ClassRunner.class) for running test (plus some config xmls to configure other properties).
Unit tests are JUnit 5 based using Mockito.

Related

Show Maven Profile

I want to build a spring-boot Java project without running the integration tests. I'm taking the approach of adding annotation
#Category(IntegrationTest.class)
and defining interface
public interface IntegrationTest {}
I have this in my pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
<configuration>
<skipTests>${maven-surefire-plugin.skipUnitTests}</skipTests>
<excludedGroups>
com.test.annotationtype.IntegrationTest
</excludedGroups>
</configuration>
</plugin>
When I run mvn install, it runs the integration test.
It's a multi-profile pom.xml, and I'd like to at least verify that the profile I think I'm running, really is the one actually run.
<profile>
<id>woodsman-default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
...
</profile>
When I run
mvn -debug install
no where in the log do I see the profile id woodsman-default. How can I get Maven to show me which profile it decided to use?
Bonus points for suggesting why it's not ignoring integration tests, but I'd settle for the easy answer.
Thx
Woodsman

how to run integration tests with maven build from eclipse or from command line

I created a integration test class "sampleIT.java",to test this class, I added run configurations for junit in eclipse under vm arguments like
-Dspring.profiles.active=it-dev
-Dspring.config.name=it-client
the test is running successfully.
I was trying to run maven build and it should also cover(run)integration test class. I added run configuration for maven build, added goals as
clean verify -Dspring.profiles.active=it-dev -Dspring.config.name=it-client
I added these contents in pom.xml
<profiles>
<profile>
<id>it</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20.1</version>
<configuration>
<includes>
<include>**/*IT</include>
</includes>
<argLine>-Dspring.config.name=it-dev</argLine>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
I tried in command line as well, but the integration test is not running
how to run maven build to run all junits and integartion tests in eclipse or from command line?

Maven profile does not affect module earlier in project list

Why won't my run configuration using a maven profile work as intended? Why does the profile fail to skip tests while the parameter does work as intended?
I have a maven run configuration which doesn't run as intended (it runs tests in lib-module which I want skipped):
-pl common,lib-module,my-module test -PdontTestLibProfile
When I run the same run config but using the maven property parameter directly:
-pl common,lib-module,my-module test -DdontTestLib=true the skipping of lib-module tests succeeds.
The maven profile dontTestLibProfile lives in the pom of my-module.
<artifact-id>my-module</artifact-id>
[...]
<profile>
<id>dontTestLibProfile</id>
<properties>
<dontTestLib>true</dontTestLib>
</properties>
</profile>
dontTestLib is a mavenProperty which is checked in the lib-module, where if it is set to true it will not run integration or unit tests.
<artifactId>lib-module</artifactId>
<properties>
<!-- Skip tests: Default is to NOT skip ==> Default is to run -->
<doneTestLib>false</dontTestLib>
</properties>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<!-- Skip Lib-Module Integration tests if skip is set -->
<skipTests>${dontTestLib}</skipTests>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<!-- Skip Lib-Module Unit tests if skip is set -->
<skipTests>${dontTestLib}</skipTests>
</configuration>
</plugin>
</plugins>
</build>
Some corollary questions which might be the cause of this issue:
Do maven profiles run in the same sequence as the project list itself, not allowing my-module to affect the lib-module which comes before it?
Do profiles only affect their own POM/module and I am trying to reach outside of the scope?

If argument in maven Surefire plugin, skip E2E tests

I couldn't seem to find anything on this but I'm curious if I can pass an argument during runtime to skip all of our projects E2E tests.
Is there anyway for me to do something like the segregated exclude block in the following pom example?
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>${argLine}</argLine>
<excludes>
<exclude unless="${skip.E2E.tests}> **/*E2E*.java</exclude>
<exclude>**/IT*.java</exclude>
</excludes>
</configuration>
</plugin>
Then I could just call mvn clean install -Dskip.E2E.tests=true. Anybody seen anything like this?
I suppose I could do something like...
<exclude>${name.of.tests.to.exclude}</exclude>
and then mvn clean install -Dname.of.tests.to.exclude=**/*E2E*.javabut I would prefer to get an easy true or false argument to set rather than this in case some of the tests I want to skip do not include E2E and I need to add them to a list.
It's hard to tell just from the snippet of your pom that you are showing, but it looks like you are using surefire for both your unit and your e2e tests. Instead, you should consider using the failsafe plugin for e2e.
One benefit is that the e2e tests will run in a different stage so you get the behavior looking for by default. They are run during the verify stage of the project build. So, you can run mvn test to run unit tests only.
You can configure your project to use fail-safe like this:
<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>
Run them using: mvn verify
Running mvn install -DskipITs will skip only integration tests, while still running unit tests.
And running mvn install -DskipTests will skip both integration and unit tests.
If you want to implement such a condition, you could use Maven profiles and have two configuration:
The default one as part of the normal build, not skipping the E2E tests
the profiled one skipping them
The profile could be then activated upon property or direct activation.
As an example you could have:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>${argLine}</argLine>
<excludes>
<exclude>**/IT*.java</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>skip.E2E.tests</id>
<activation>
<property>
<name>skip.E2E.tests</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>${argLine}</argLine>
<excludes>
<exclude>**/*E2E*.java</exclude>
<exclude>**/IT*.java</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
Note: the default Maven Surefire Plugin applying to normal build and then a profiled one.
Running:
mvn clean install
Will not activate the profile and your build will skip the tests. While running:
mvn clean install -Pskip.E2E.tests
or
mvn clean install -Dskip.E2E.tests=true
Will activate the profile and as such add the exclusion to the tests execution.
So this is exactly the scenario you were looking for, I presume.
Alternatively and as suggested by #AndrewEisenberg in the another answer, you could use the Maven Failsafe Plugin for different type of tests. The main two differences are that: it has different phase bindings AND when it fails, it does it in a safer way. As from official documentation:
If you use the Surefire Plugin for running tests, then when you have a test failure, the build will stop at the integration-test phase and your integration test environment will not have been torn down correctly.
The Failsafe Plugin is used during the integration-test and verify phases of the build lifecycle to execute the integration tests of an application. The Failsafe Plugin will not fail the build during the integration-test phase, thus enabling the post-integration-test phase to execute

exclude maven module with intergration tests from test phase

I have a multi module maven project with a structure
parent
pom.xml
module
pom.xml
core-api
pom.xml
integ-tests
pom.xml
I have maven surefire plugin setup for executing the unit tests '*Test.java' which are houses in the 'core-api' module.
We have slow long-running integration tests housed in a separate 'integ-tests' module. we use '*Test.java' for our integ tests as well.
We need to be able to compile all source code but want to exclude the 'integ-test' from running as part of the default maven 'test' phase. We plan to use a profile to enable the test phase of the 'integ-test' module. I don't want to use the 'failsafe' plugin.
A matrix outlining the combination is here
mvn | core | integ-test
test | run unit tests | exclude
test -PintegTest | unit tests | integ tests
I've defined the surefire plugin in my parent pom, with a property 'skip.integ.tests' which will be controlled via a profile '-PintegTests'.
<properties>
<skip.integ.tests>true</skip.integ.tests>
</properties>
..
<build>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
</build>
..
<profiles>
<profile>
<id>integTests</id>
<properties>
<skip.integ.tests>false</skip.integ.tests>
</properties>
</profile>
</profiles>
In my 'integ-test' pom, i've then overridden the 'maven-surefire-plugin' config and have the 'skipTests' configuration set to look at the value of the property.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>${skip.integ.tests}</skipTests>
</configuration>
</plugin>
</plugins>
</build>
My problem is the integ-test module tests run in every case. Any ideas on where i'm going wrong with the setup?
First you should name your integration tests accordingly to the naming conventions of the maven-failsafe-plugin which is intended to run the integration tests. Furthermore the pre-integration-test, integration-test and post-integration-test life cycle phases are intended for running those tests. This means in your case to configure the maven-failsafe-plugin accordingly to the documentation like this. The maven-failsafe-plugin bounds to the integration-test life cycle phase.
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.16</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
</project>
I would suggest to add the following profile into your integration test module like this:
<profiles>
<profile>
<id>run-its</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.16</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
This gives you simply the following options:
mvn test
running unit tests only
mvn -DskipTests=true test
running compilation etc. but no unit tests.
mvn -Prun-its verify
Running packaging etc. unit tests and integration tests
mvn install
Running installation without integration tests.
mvn -DskipTests=true install
Running installation without running unit tests nor integration tests.
In your Maven build, you can exclude:
compilation and execution of both unit tests (by Surefire plugin) and integration tests (by Failsafe plugin) by adding -Dmaven.skip.test=true
execution of both unit and integration tests via -DskipTests
execution of integration tests via -DskipITs
Instead, if you have your integration tests in a separate Maven module (i.e. integ-test in your case), you can directly exclude that from the Maven build via profile, like in below example -- see extract of aggregator's pom.xml and maven command line to be launched:
<modules>
<!-- remove 'integ-test' from this list -->
</modules>
<profiles>
<profile><id>build-it</id>
<activation><activeByDefault>true</activeByDefault></activation>
<modules><module>integ-test</module></modules>
</profile>
</profiles>
and then mvn install -P !build-it

Resources