Offline instrumentation using jacoco and gradle - java

I want to do offline instrumentation to get coverage for my project because without that, for the server managed things (EJB's) it is showing coverage as 0%. Does anyone know how can we do offline instrumentation with gradle?
EDIT: I'm using Wildfly 8.2 application server

I don't use JaCoCo, but I've used Cobertura. As far as I know, the main superficial difference between them is that JaCoCo does runtime instrumentation, and Cobertura does compile-time instrumentation. If have no idea whether your issue with JaCoCo is fixable, but if you need to do offline or compile-time instrumentation, then you should use Cobertura.
Processing with Cobertura is as as easy as this:
plugins {
id 'net.saliman.cobertura' version '2.2.5'
}
apply plugin: 'java'
test {
filter {
includeTestsMatching "*Test"
}
}
test.dependsOn coberturaCheck
cobertura {
coverageCheckBranchRate = 0
coverageCheckLineRate = 0
coverageCheckPackageBranchRate = 0
coverageCheckPackageLineRate = 0
coverageCheckTotalBranchRate = 0
coverageCheckTotalLineRate = 0
}

Related

Why is PMD give different results for Eclipse and Gradle?

I am using the eclipse-pmd plugin, and I am also using PMD via the following Gradle configuration:
plugins {
id 'pmd'
}
pmd {
consoleOutput = true
ruleSets = []
ruleSetFiles = files("pmd-ruleset.xml")
toolVersion = "6.41.0"
}
Both methods are configured to use the same ruleset, and my PATH variable points to PMD 6.41.0 (which I think is what the Eclipse plugin uses), and yet both give different results.
For example, running ./gradlew pmdMain complains about the rule AvoidUncheckedExceptionsInSignatures, but eclipse-pmd does not flag this up at all.
Why might this be?
It turns out that the eclipse-pmd plugin (which I found in C:\Users\{username}\.p2\pool\plugins) comes packaged with its own version of PMD, which in this case is 6.28.0.
This doesn't fully explain the discrepency, since the AvoidUncheckedExceptionsInSignatures rule has been around since PMD 6.13.0, but I'm happy enough to blame the difference in versions for the difference in output.

Detaching default functionality from gradle lifecycle tasks

Tl;dr
Is there a way to detach specific plugin behavior (such as checkstyle's check behavior) from existing gradle lifecycle tasks (gradle check, in this particular case)?
Longer version
In our current gradle Java project setup, we've included checkstyle as one of our plugins for static code checking. It currently runs as a part of Jenkins pipeline through gradle's build task. While this has mostly worked out for what we've needed - namely running our tests and making sure we're sticking to code standards - I've also noticed that we could make our feedback loop a little faster if we could run just the checkstyle's plugin's checks before build kicks in the tests.
To do so, as far as I understand, we'd have to create a custom task that runs only the checkstyle functions checkstyleMain and checkstyleTest and decouple the default checkstyle behavior from gradle's build lifecycle task. I've been looking through both gradle and the checkstyle plugin's docs, but quickly found I'm out of my depth.
Code:
plugins {
id "checkstyle"
}
checkstyle {
toolVersion "8.24"
configFile file("config/checkstyle/checkstyle.xml")
}
checkstyleMain {
source = "src/main/java"
}
checkstyleTest {
source = "src/test/java"
}
That is everything checkstyle related inside of build.gradle, the check task itself isn't customized.

Sonar Code Coverage reduces after JacocoMerge

I am trying to generate sonar report for my multi-module java project. But after doing jacocoMerge I see the coverage reduces drastically. See the below screenshots:
Code coverage with Unit and Integration Separate:
Code coverage After JacocoMerge:
I used below code to merge the coverage:
task jacocoMergeAll(type: JacocoMerge) {
dependsOn(subprojects.test)
subprojects.each { subproject ->
def testTask = subproject.tasks.withType(Test)
if(new File("$subproject.buildDir/jacoco/test.exec").exists()){
executionData(testTask)
}
}
}
I am using sonarQube version 5.6.3 and jacoco plugin version is 0.7.7.201606060606.
Why does the coverage drop after jacocoMerge? Please help.

Integrating Sonar, Jacoco, Gradle, ScalaTest with Junit, Java

I have very successfully integrated Gradle (1.11), Sonar ( 4.1.1 ), Java, Scala and Jacoco in my build process. I even managed to get info regarding the number of successful tests ( thanks to Stackoverflow! ). I have one problem though.
I can't seem to get info about coverage per test. It would be very nice to have this info.
> 15:11:16.514 INFO - Sensor JaCoCoSensor... 15:11:16.535 INFO -
> Analysing C:\example\gradle-sonar-jacoco-scala\build\jacoco\test.exec
> 15:11:17.887 INFO - No information about coverage per test.
A simplified version of the project is at : https://github.com/sebastianharko/gradle-sonar-java-jacoco-scalatest-junit
Cheers !
It Looks like you already have
apply plugin: 'jacoco'
in your gradle.build
But i'm not seeing a definition to where it's to get it file from in the gradle.build
jacoco {
destinationFile = file("$buildDir/jacoco/test.exec")
}
If you plan on doing integration and unit testing it would look similar to the following:
task "integtest"(type: Test, dependsOn: integtestClasses) {
testClassesDir = sourceSets.integtest.output.classesDir
classpath = sourceSets.integtest.runtimeClasspath
jacoco {
destinationFile = file("$buildDir/jacoco/integTest.exec")
}
}
test {
jacoco {
destinationFile = file("$buildDir/jacoco/test.exec")
}
}
With the corresponding sonar configuration items
property "sonar.jacoco.reportPath", "$buildDir/jacoco/test.exec"
property "sonar.jacoco.itReportPath", "$buildDir/jacoco/integTest.exec"
I've seen another conf parameters from SonarQube - integrationTest.exec - sonarRunner (Gradle) or "sonar-runner" command - showing 0.0% covereage :
The parameter sonar.java.coveragePlugin=jacoco called my attention. Did you try that?
You may also want to use Coveralls.io
It's very cheap: only $4.99/mo. and you would have a deep integration with your pull requests on Github (track when a branch increases or decreases your code coverage) as well as a very nice UI to drill down into your code coverage.
Both SBT and Gradle integrations are available.

Exclusions not working with Jacoco Gradle plugin

I'm working on setting up the Jacoco Gradle plugin for my project. The plugin is executing fine and generating the coverage report but it's not excluding packages that I would excluded.
Classes I would like to include are in com/xxx/ws/hn/** and classes I would like excluded are in com/xxx/ws/enterprise/**.
Here's my Gradle script:
apply plugin: "jacoco"
jacoco {
toolVersion = "0.6.2.201302030002"
reportsDir = file("$buildDir/reports/jacoco")
}
test {
jacoco{
excludes = ["com/xx/ws/enterprise/**/*"]
includes = ["com/xxx/ws/hn/**/*"]
append = false
}
}
jacocoTestReport {
dependsOn test
description = "Generate Jacoco coverage reports after running tests."
executionData = files('build/jacoco/test.exec')
reports {
xml.enabled true
html.enabled true
}
}
Am I missing anything here? I've tried various patterns of exclusions including a '.' delimiter for packages instead of a '/' but nothing seems to work. Any help would be greatly appreciated.
I have not verified this but when I read the JaCoCo documentation, it states that wildcards can be used but all examples only have ONE *, not two as your example shows.
http://www.eclemma.org/jacoco/trunk/doc/agent.html
To solidify (and verify) Joachim's answer, I came across this SO post and found that specifying canonical class names, classpath style (with slashes, not periods), with single wildcard characters actually worked well. For example, here is my exclude list that works in my build, as defined as a list in a separate gradle file:
def testExcl = [
'android/*',
'com/android/*',
'com/nativelibs4java/*',
'com/ochafik/*',
'com/fasterxml/*',
'com/esotericsoftware/*',
'com/google/*',
'com/lmax/*',
'com/sun/*',
'jdk/*',
'mockit/*',
'org/apache/*',
'org/bridj/*',
'org/gradle/*',
'org/hamcrest/*',
'org/junit/*',
'org/slf4j/*',
'sun/*',
'worker/*',
'*Test',
'*TestIntegration',
'*AllTests',
'*Suite'
]
I tried probably 10 or 12 other ways of formatting the class names, and this is the only way that actually worked.
I don't know why something like this that is so simple/fundamental is so ungoogleable and difficult to find a definitive answer on in the context of Gradle (i.e. outside JaCoCo's official documentation, where no documentation exists about Gradle integration, but Ant and Maven integration docs are there).
Hopefully this helps if others are flailing trying to get JaCoCo to exclude classes.
UPDATE:
This changed in Gradle 7 (I went from 5.6.1 to 7.1.1, so not sure about Gradle 6) and no longer works.
For Gradle 7 you need to replace / with .; here are my updated exclusions:
def testExcl = [
'android.*',
'com.android.*',
'com.nativelibs4java.*',
'com.ochafik.*',
'com.fasterxml.*',
'com.esotericsoftware.*',
'com.google.*',
'com.lmax.*',
'com.sun.*',
'jdk.*',
'mockit.*',
'org.apache.*',
'org.bridj.*',
'org.gcpud.common.*',
'org.gcpud.testutil.*',
'org.gradle.*',
'org.hamcrest.*',
'org.junit.*',
'org.slf4j.*',
'sun.*',
'worker.*',
'*Test',
'*Test$*',
'*TestIntegration',
'*AllTests',
'*Suite'
]
Also see the following SO post for other means of excluding classes from reporting (exclude from reporting, not coverage itself):
Filter JaCoCo coverage reports with Gradle

Categories

Resources