Jenkins jacoco plugin is not obeying includes in pom.xml - java

I've got a pom.xml that looks roughly like this:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.1</version>
<configuration>
<includes>
<include>my/package/path/**/*</include>
</includes>
</configuration>
<!-- more stuff -->
</plugin>
When I run my unit tests then call mvn jacoco:report locally on my laptop, everything is fine, and only the stuff in my.package.path is included. My coverage is 86%. However, when I let Jenkins run the unit tests, using the same commands, then call jacoco(execPattern:'target/jacoco.exec') in my Jenkinsfile, I end up with all code included in the report attached to the build, so my coverage ends up being 2% because I didn't write tests for a bunch of 3rd party libraries.
How do I fix this?

You may exclude the 3rd party packages:
<excludes><!-- Exclude class from test coverage -->
<exclude>**/*com/3rdparty/path/*</exclude>
</excludes>

I was able to solve it by using the inclusionPattern parameter in the call to jacoco:
jacoco(execPattern: 'target/jacoco.exec',inclusionPattern: 'my/package/path/**/*')

Related

Unable to run JUnit tests in parallel in maven

I have been searching for this everywhere and whilst there are documentations and answers all over the place, I can't seem to be able to make this work
I am currently working on a multi-modules project with thousands of tests and because these take hours to run, I thought it will be a good idea to run them in parallel(just the tests not the modules)
To achieve this, I found out that jUnit 4.7 or later with maven-surefire-plugin can be used to run tests in parallel
Here's my configuration
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<parallel>classes</parallel>
<threadCount>10</threadCount>
<argLine>-Xverify:none
-enableassertions -Djava.util.Arrays.useLegacyMergeSort=true #{argLine}</argLine>
<useSystemClassLoader>false</useSystemClassLoader>
<includes>
<include>**/*Test.java</include>
<include>**/Test*.java</include>
</includes>
<excludes>
...
...
</plugin>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M3</version>
<configuration>
<includes>
<include>**/*Test.java</include>
<include>**/Test*.java</include>
</includes>
<!-- Required until JDK >=1.7.0u72, see https://code.google.com/p/powermock/issues/detail?id=504 -->
<runOrder>alphabetical</runOrder>
<argLine>#{argLine}</argLine>
</configuration>
</plugin>
Running on Apache Maven 3.3.9
There are all kind of tests, (RunWith, PowerMock,BeforeClass,Before etc)
Here's what I'm doing to test if my configuration is working or not
First I build all the modules
mvn clean install -Pbuild-all -DskipTests
Next I run the specific module tests using the following command line
mvn test -DfailIfNoTests=false -pl module1
The above doesn't seem to be running in parallel as I get stuck in some tests and it doesn't go any further
Furthermore, I tried to run multiple jUnit test classes rather than everything in the module but I'm not sure whether they are running in parallel, I used the following command
mvn test -DfailIfNoTests=false -Dtest=testClass1,testClass2,testClass3 -pl module1
The above finishes in 20 seconds but I'm not sure whether it has run in parallel
Is there anything I'm missing?

Maven code coverage

I am new to java world. Our team is using Maven to building everything into single .war file. I am looking for tools to instrument .war files to enable code coverage. Idea is to manually instrument .war file and then run the test.
I looked at couple of tools, but not getting exactly what I am looking for e.g. Emma, jester, cobertura etc. Looking for simple instructions.
If you want to measure code coverage you should use Jacoco. It allows measuring for unit tests and integration tests as well.
All you have to do is to add dependecy:
<dependency>
<groupid>org.jacoco</groupid>
<artifactid>org.jacoco.core</artifactid>
<version>0.6.2.201302030002</version>
<scope>test</scope>
</dependency>
and add jacoco-maven-plugin. Please note that if you won't use Sonar then you have to replace ${sonar.jacoco.reportPath} properties with raw file paths
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.6.2.201302030002</version>
<executions>
<!-- prepare agent for measuring unit tests -->
<execution>
<id>prepare-unit-tests</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<destFile>${sonar.jacoco.reportPath}</destFile>
</configuration>
</execution>
<!-- prepare agent for measuring integration tests -->
<execution>
<id>prepare-integration-tests</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<phase>pre-integration-test</phase>
<configuration>
<destFile>${sonar.jacoco.itReportPath}</destFile>
<propertyName>itCoverageAgent</propertyName>
</configuration>
</execution>
</executions>
</plugin>
If you want also to use sonar, then specify such properties:
<properties>
<!-- select JaCoCo as a coverage tool -->
<sonar.core.codeCoveragePlugin>jacoco</sonar.core.codeCoveragePlugin>
<!-- force sonar to reuse reports generated during build cycle -->
<sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
<!-- set path for unit tests reports -->
<sonar.jacoco.reportPath>${project.basedir}/target/jacoco-unit.exec</sonar.jacoco.reportPath>
<!-- all modules have to use the same integration tests report file -->
<sonar.jacoco.itReportPath>${project.basedir}/../target/jacoco-it.exec</sonar.jacoco.itReportPath>
</properties>
You can find more details on http://www.kubrynski.com/2013/03/measuring-overall-code-coverage-in.html
Cobertura would support that. See the answer to this question.
Java: measure code coverage for remote scripting tests
If you want to do this in development rather than on your build server, you might want to give eclemma a try. You can launch your webapp in your IDE with eclemma and then simply run whatever test you want to run (outside of eclemma) and it will nicely annotate the code that is running with green.

Maven Surefire only acknowledges "forkMode" on the command line

We have our POM defining the maven-surefire-plugin as follows:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.14</version>
<configuration>
<reuseForks>false</reuseForks>
<forkCount>1</forkCount>
<argLine>-Xms64m -Xmx256m</argLine>
<includes>
<include>**/*Test.java</include>
</includes>
</configuration>
</plugin>
However, our Java tests (which involve some parallel tests and static singletons) only run properly when we run our test phase/build using:
mvn test -DforkMode=always
Strangely, even if we change our <configuration> to use (instead of the newer options):
<forkMode>always</forkMode>
And run:
mvn test
It will fail. But then if we run:
mvn test -DforkMode=always
It will pass. Instead of the newer options, it still will only work if we explicitly provide forkMode on the command line. We have tried this with multiple versions of the surefire plugin, to the same effect.
Are there any locations where this property could be overridden, or known issues in which the XML configuration is not properly used?
Rookie mistake. The configuration I was using was listed in a separate <profile> block that was not being executed. The profile with:
<activeByDefault>true</activeByDefault>
Did not include its own Surefire configuration at all (so it didn't show up in a search), and was using inherited values, which explains why the command-line system properties were able to affect its behavior.

Testing Clojure and Java simultaneously

I'm developing a library that contains both Clojure and Java code, using Eclipse + Maven to manage the project.
I have a good set of JUnit tests that cover the Java portion of the code base, and also have a separate set of Clojure tests written using the standard clojure.test toolset.
Ideally I'd like to be able to run all tests simultaneously as part of the build process. I have the clojure-maven-plugin installed, but it still only seems to run the JUnit tests and ignores the Clojure ones.
How can I achieve this?
OK, I figured out how to do this myself with a little help from the information in the answers to this question on testing Clojure with Maven.
The trick was to add the following section to the pom.xml:
<build>
<plugins>
<plugin>
<groupId>com.theoryinpractise</groupId>
<artifactId>clojure-maven-plugin</artifactId>
<version>1.3.8</version>
<executions>
<execution>
<id>test-clojure</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<testResources>
<testResource>
<directory>src/test/clojure</directory>
</testResource>
</testResources>
</build>
This has the effect of running the Clojure test cases as part of the standard Maven test goal.
EDIT
As of 2012, a good alternative is to use cljunit to run the Clojure tests as part of a regular JUnit test suite.

Generating a maven site including a Cobertura Report

I've got some projects that are already doing site generation via maven, and I want to integrate cobertura reports in them, but no maven goal I seem to run will generate a local preview for me to look at that includes the Cobertura reports in the site. I want to be sure they're generating correctly before I commit the pom changes to the repo and have broken site generated.
Below is what I've added to the maven poms (parent and module), but the site I see when I run mvn site:run does not include the cobertura reports:
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<configuration>
<check>
<haltOnFailure>false</haltOnFailure>
<regexes>
<regex>
<pattern>parent-package-name-here.*</pattern>
<branchRate>80</branchRate>
<lineRate>80</lineRate>
</regex>
</regexes>
</check>
<instrumentation>
<includes>
<include>parent-package-name-here/**/*.class</include>
</includes>
</instrumentation>
</configuration>
<executions>
<execution>
<id>clean</id>
<phase>pre-site</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
<execution>
<id>instrument</id>
<phase>site</phase>
<goals>
<goal>instrument</goal>
<goal>cobertura</goal>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
<reporting>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
</plugin>
</plugins>
</reporting>
...
</project>
What maven command should I use to generate the site with cobertura reports? Or, what should I add (additionally) to get the site generation to include the cobertura reports?
Should do:
mvn site
To elaborate, running mvn a:b runs the goal b in plugin a. Saying mvn c means to run the lifecycle phase c, which runs all of the bound goals in all of the phases up to c. As a result, this will trigger a lot more things to happen (such as doing the necessary preparation to produce cobertura reports).
I figured out how to do this.
It seems there are a lot of bugs in the link generation within the maven site generation plugin.
The only way I've found to make maven generate a local copy of the site with working module links is to modify the distributionManagement/site tag to point to some local directory instead of the real-live deploy directory, then use maven site:deploy.
Every attempt to use mvn site:stage generates broken links. Same goes for mvn site:run.
The report links work with mvn site:run / mvn site:stage but the links to modules do not.
mvn site
should do what you are looking for. You configure the plugin to run in the pre-site and site phases of the life cycle but your are then executing the site:run goal not site. We are doing similar things with clover (commercial coverage tool) and mvn site does the trick.
site:stage module links don't work in my experience either for multi module builds but site:deploy does. Try this:
Use a property for the site URL in the parent pom, e.g. ${site.url}. Then call this
mvn clean site site:deploy -Dsite.url=file://`pwd`/target/site-deployed
The pwd is a -nix command that will substitute the current directory. This is because the URL that you use must be absolute.
We use
mvn site-deploy
This builds the site and deploys it (copies it to the place we have configured).
mvn site:site should produce what you are after, in the target directory, there will be a site directory containing all reports linked with an index.html in that directory.

Categories