How to write a Maven plugin IT test that correctly fails its build, resulting in an overall pass? - maven

When generating a skeleton Maven plugin from archetype, the new project includes a Maven project under the src/it directory. It is an integration it (hinted at by the it dir name) and fresh out-of-the-box it passes when run during Maven's integration-test phase.
There are nearly 10 such IT Maven projects, a subset of which intentionally result in BUILD FAILURE, and attendant verify.groovy scripts that ensure those builds fail for the correct reason. Ideally each IT test sub-build that fails for the correct reason results in that IT test passing, but by including any of these failing IT tests as part of the whole integration test suite causes the overall Maven run to fail as well, which is incorrect in my case.
How do I coax Maven to run those failing Maven sub-builds, ignore their build results, but honor the results of their Groovy verification scripts?
Edit: One IT test (disabled) is committed here.

If you like to write an integration test which is intended to fail as a result
you have to express this via the invoker.properties file like this:
invoker.buildResult=failure
The full description of the file can be found in the documentation.

Related

What is the difference between 'mvn verify' vs 'mvn test'?

I'm bit confused with mvn verify phase. I've created a Spring Boot project (a simple project, without any explicit configurations added). I've created a few JUnit unit tests which are run with both the mvn verify and mvn test commands.
There isn't any difference observed in the mvn verify and mvn test command output.
What does mvn verify do different than mvn test?
Also some posts on Stack Overflow mentions that mvn verify runs the integration tests. If this is the case then I have few questions.
How does Maven identify a specific test as a unit test or integration test?
If mvn verify is supposed to run only the integration tests, then why are unit tests executed with it?
First of all, when you run a Maven goal, it will run any previous goal. The order of basic phases is:
Validate
Compile
Test
Package
Verify
Install
Deploy
If you run Test, Maven will execute validate, compile and test. Based on this, the first point is that verify includes test.
Based on official documentation:
TEST - test the compiled source code using a suitable unit testing framework. These tests should not require the code be packaged or deployed
VERIFY - run any checks on results of integration tests to ensure quality criteria are met
To run unit tests, the Surefire plugin is recommended. And Failsafe for integration tests.
The verify command executes each default lifecycle phase in order (validate, compile, package, etc.), before executing verify. In most cases the effect is the same as package. However, in case there are integration tests, these will be executed as well. And during the verify phase some additional checks can be done, e.g. if your code is written according to the predefined checkstyle rules.
Conclusion: if you want to run your integration tests and check it, use verify. If you only want to run unit tests, use test.
My personal advice: if in doubt, use verify.
How does Maven identify a specific test as a unit test or integration test?
Integrations Test always takes a name like IT.java or IT.java or *ITCase.java

How to include Unit and Integration test in Sonar Code Coverage

I am using below commands to build my maven code.
Compile-
-DargLine="-DDB_SERVER=localhost -DDB_PORT=5432 -DDB_NAME=sample -DDB_USER=sample -DDB_PASSWORD=sample -DDB_MAX_POOL=10" -Dcom.sample.redis=false clean compiler:compile
Unit-Test Analysis-
DargLine=-DDB_SERVER=localhost -DDB_PORT=1234 -DDB_NAME=sample -DDB_USER=sample -DDB_PASSWORD=sample -DDB_MAX_POOL=10 -Dcom.sample.redis=false -Dcobertura:cobertura-integration-test -Dcobertura.aggregate=false -Dcobertura.report.format=xml integration-test test
And using below sonar properties to capture xml to publish in sonar.
sonar.projectKey=sample
sonar.projectName=sample
sonar.projectVersion=$PipelineId
sonar.modules=admin,client-api,common,om,serviceproviders
sonar.cobertura.reportPath=target/site/cobertura/coverage.xml
sonar.sources=.
sonar.skipPackageDesign=true
sonar.sourceEncoding=UTF-8
Being Multi module the code coverage is showing only 9.4%. Am I missing anything. I don't see any error logs as well.How can I achieve the same using coverage tool like Jacoco.
SonarQube - Version 5.1.1 - LGPL v3
Maven has a lifecycle Maven Lifecycle where each of the targets includes the ones before it. e.g. "test" includes "compile", "integration-test" includes "test", etc. You generally need to only include the target at the tip of the lifecycle. e.g. "mvn test" means (compile AND run the tests).
I'm thinking you want to run the "mvn verify" goal, which is compile, run tests and integration tests, and then run verifications (coverage checks, etc). Cobertura has a plugin that should integrate with maven and tap into various goals to run its pieces at appropriate times. I'm guessing you are messing up cobertura by having multiple targets and trying to break it into pieces - i.e. overwriting the instrumentation or something.
Similarly, you might find using jacoco easier than cobertura. It hides the instrumentation, and integrates pretty seemlessly with maven.
Good luck.

how to clean jacoco.exec after running integration tests in a multi-module project

I have a multimodule Maven project, it is analyzed using the Sonar Maven runner and coverage is done with Jacoco. For our integration tests we want to see the coverage across all modules (because they are integration tests after all).
Therefore we configure the jacoco-it.exec file to be in ${user.dir}, with the appendproperty to true. This way all modules append their information to the same location and coverage is calculated over all modules.
But since append is true the file will still be there on a next run, since it isn't placed in a directory that maven cleans. This leads to incorrect coverage reports.
What is the best way to clean up this file after a sonar run? Ideally I would like to configure this in the same pom profile as our jacoco/sonar configuration, so that no other projects need to remember to set a clean step in Jenkins or whereever. The sonar/jacoco configuration is in a company wide parent pom file.
Since you are using Maven, you could try and use the maven-antrun-plugin to delete the file.
I don't know how you run Sonar Maven, but you can either bind the maven-antrun-plugin task to a phase after the one the Sonar Maven Runner is bound to (and you would have the file deleted automatically and the end of each run) or you can call the maven-antrun-plugin from the command line.

how to execute all the invoke top level maven target in jenkins and execute remaining build steps only if maven target are successful

I have a Continuous integration setup using jenkins. I need to run Junit test cases and selenium test cases and commit the jar files in svn, only if all the junit and selenium scripts are passed.
Junit and selenium test cases are separate maven projects so i have used two invoke top level maven targets (One for selenium and other for Junit). I came across following issues,
Selenium scripts will be executed first and if any of the selenium test cases are failed, the jenkins build is marked as Failed and it will start to execute the post-build actions skipping all the build steps including junit. I want to run the Junit test cases also even if selenium scripts are failed. So i have added -Dmaven.test.failure.ignore=true in maven goals to execute the junit test cases even if selenium scripts are failed. This worked perfectly as i expected and continued to execute junit test caes and the build is marked as UNSTABLE.
Now i got another issue, i have a build step to invoke ant at the end (To commit jars in svn only if selenium and junit are passed). After adding -Dmaven.test.failure.ignore=true, the jars are getting commited to svn even if there is any failures.
Can anyone help me to solve this problem?
The build should run both Selenium and Junit, even if there is any failure in any one of project.
Jars should be committed in svn only if everything is successful (This is done by using ant target, so i have placed invoke ant at the end in Build step.
Is there any other way to accomplish this ? Thanks in advance.

Avoiding circular dependencies between Maven plugin build and test

I have a project with the following subprojects:
foo-codegen
...which, as the name implies, performs code generation...
foo-maven-plugin
...which invokes foo-codegen during the build process.
Generally speaking, this works fine. The problem, though, is when I want to test foo-codegen: foo-maven-plugin isn't yet available during foo-codegen's build cycle if we're putting things together in dependency order, but the build process for the tests invokes that plugin to actually perform the necessary code generation.
What's the right way to break this chain? Should I move foo-codegen's tests into a third subproject? Use the Maven Invoker plugin rather than foo-maven-plugin for doing code generation during the test phase? Something else?
If you do a mvn install or mvn deploy to a repository on the plugin first, then you can run them any order and do a mvn compile separately.

Resources