Gradle skipping jacoco coverage plugin - gradle

I know there are a lot of similar questions for this on stackexchange but this is driving me crazy and nothing from any other answers have helped me. I've used just about every force flag for gradle I can find.
My Gradle version is 2.2.1
My build.gradle
buildscript {
ext {
springBootVersion = '1.5.3.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath("se.transmode.gradle:gradle-docker:1.2")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'application'
apply plugin: 'docker'
apply plugin: 'jacoco'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
ext {
springCloudVersion = 'Dalston.RELEASE'
}
test {
include 'src/test/java'
finalizedBy jacocoTestReport
}
jacocoTestReport {
reports {
xml.enabled true
csv.enabled false
html.enabled false
xml.destination "${buildDir}/jacoco"
}
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
When I run gradle test or gradle clean test jacocoTestReport or gradle clean --re-run etc etc I get the same results.
gradle test
:compileJava
:processResources
:classes
:compileTestJava
:processTestResources UP-TO-DATE
:testClasses
:test UP-TO-DATE
:jacocoTestReport SKIPPED
I have only 1 test in the src/test/java location.
Why will it not generate the reports and run? I'm at a loss.

Remove the wrong include statement in your test configuration.
That seems to cause the test task to always be up-to-date (not executing any test as the include pattern isn't matched)
The jacocoTestReport will be skipped if there's no execution data available that is needed to generate the report. This execution data should be generated while the test task is executed. In your example we see that the test task is always marked as up-to-date (because of the invalid include statement) causing the build to never produce any input for the jacocoTestReport task.

For Spring 2.5 Users, who got stuck with it for hours -just like myself.
I was not having the exec file generated.
And because of that ,
I found that the jacocoTestReport was simply "skipped".
I got it fixed by adding :
test {
useJUnitPlatform()
finalizedBy jacocoTestReport // report is always generated after tests run
}
That's because I'm using Junit5 with spring boot 2.X

It was a bit tricky to find that JaCoCo by default skips every jacocoTestCoverageVerification task in case if tests are run trough a custom named task (not just test).
For example, tests were run via unitTest in my project, JaCoCo did create build/jacoco/unitTest.exec during their execution, yet it kept searching for test.exec during verification. ¯\_(ツ)_/¯
The workaround is to override executionData path for JaCoCo gradle tasks:
apply plugin: 'jacoco'
jacoco {
toolVersion = "0.8.8"
}
def coverageFile = layout -> layout.buildDirectory.file('jacoco/coverage.exec').get()
tasks.named('jacocoTestCoverageVerification') {
getExecutionData().setFrom(files(coverageFile(layout)))
violationRules {
rule {
limit {
minimum = project.properties['testCoverageThreshold'] ?: 0.5
}
}
}
}
tasks.named('jacocoTestReport') {
getExecutionData().setFrom(files(coverageFile(layout)))
}
tasks.named('unitTest') {
jacoco {
destinationFile = coverageFile(layout).asFile
}
finalizedBy jacocoTestReport, jacocoTestCoverageVerification
}

Related

How do I get a Jacoco coverage report using gradle plugin when all my tests are in a separate submodule

I'm having trouble setting up jacoco coverage for my java project since I'm new to gradle. My final goal is to connect this to sonarqube. All my tests are in a separate module
structure:
./build.gradle
settings.gradle
./submodule1/build.gradle
./submodule1/src/main/java/prismoskills/Foo.java
./submodule2/build.gradle
./submodule2/src/main/java/com/project/prismoskills/Bar.java
./test/build.gradle
./test/src/test/java/prismoskills/TestFooBar.java
One way I can think of is to set additionalSourceDirs in test module and enable jacoco only in root and test module.
The problem with this approach is that my project has a lot of sub modules(which I haven't shown here) and I am having trouble passing additionalsourcedirs to test module's JacocoReport task in an automated way.
Also it looks like this use case can be handled in maven easily by referring to this
https://prismoskills.appspot.com/lessons/Maven/Chapter_06_-_Jacoco_report_aggregation.jsp
Any leads on how to proceed further with gradle will be appreciated. Thanks in advance
gradle version: 6.4
jacoco gradle plugin version: 0.8.5
I think the following solution should solve your problem. The idea is that:
JaCoCo exec file is generated for every project
at the end one XML report with all data is generated
It does the same for JUnit reports because it is easier to see all tests reports together in the root project instead of navigating between directories.
plugins {
id 'base'
id 'org.sonarqube' version '3.0'
}
allprojects {
apply plugin: 'jacoco'
apply plugin: 'project-report'
// ...
jacoco {
toolVersion = 0.8.5
}
}
subprojects {
// ...
test {
reports.html.enabled = false
useJunitPlatform()
finalizedBy jacocoTestReport
}
jacocoTestReport {
dependsOn test
reports.html.enabled = false
}
}
// ...
task testReport(type: TestReport) {
destinationDir = file("${buildDir}/reports/test")
reportOn subprojects*.test
}
task jacocoTestReport(type: JacocoReport) {
subprojects { subproject ->
subproject.tasks.findAll { it.extensions.findByType(JacocoTaskExtension) }.each { extendedTask ->
configure {
sourceSets subproject.sourceSets.main
if (file("${subproject.buildDir}/jacoco/${extendedTask.name}.exec").exists()) {
executionData(extendedTask)
}
}
}
}
reports.xml.enabled = true
}
rootProject.getTasksByName('test', true).each {
it.finalizedBy(testReport)
it.finalizedBy(jacocoTestReport)
}
This line
if (file("${subproject.buildDir}/jacoco/${extendedTask.name}.exec").exists()) {
is added to prevent build failures when some subprojects don't have tests at all.
Following can be defined in the build.gradle of root project. Jacoco plugin will be applied to all the submodules.
subprojects{
plugins{
id 'java'
id 'jacoco'
}
test.finalizedBy jacocoTestReport
}

CorDapp JaCoCo Code Coverage

I have a Corda based project with several CorDapp sub projects. I've been looking to add JaCoCo code coverage to this project. I'm looking to have a single code coverage report draw in an aggregate report of all the subproject JaCoCo reports.
To add JaCoCo to a maven project with several maven sub projects, I followed this blog entry https://lkrnac.net/blog/2016/10/aggregate-test-coverage-report/. After we ran the build ./gradlew clean test and got our reports, one of our team members noted that the whitelists weren't being created properly anymore when we ran ./gradlew clean deployNodes.
I've gone back to the base Kotlin CorDapp template found here https://github.com/corda/cordapp-template-kotlin to rule out if it's something we've done wrong with our project structure/gradle. Without JaCoCo added, I see all the whitelist entries I would expect. Once I add the JaCoCo code, I only see the 5 default Corda whitelist entries, and none of my added contract entries.
I'm using JaCoCo version 0.8.1 and coveralls version 2.6.3. The changes I've made are all within the build.gradle file for the root directory cordapp-template-kotlin:
subprojects {
repositories {
mavenCentral()
}
apply plugin: 'jacoco'
apply plugin: 'java'
group = 'net.lkrnac.blog'
version = '1.0-SNAPSHOT'
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
dependencies {
testCompile("junit:junit:4.12")
}
jacoco {
toolVersion = jacoco_version
}
//command for generating subproject coverage reports
jacocoTestReport {
reports {
xml.enabled false
csv.enabled false
html.destination file("${buildDir}/jacocoHtml")
}
}
}
def publishedProjects = subprojects.findAll()
task jacocoRootReport(type: JacocoReport, group: 'Coverage reports') {
description = 'Generates an aggregate report from all subprojects'
dependsOn(publishedProjects.test)
additionalSourceDirs = files(publishedProjects.sourceSets.main.allSource.srcDirs)
sourceDirectories = files(publishedProjects.sourceSets.main.allSource.srcDirs)
classDirectories = files(publishedProjects.sourceSets.main.output)
executionData = files(publishedProjects.jacocoTestReport.executionData)
doFirst {
executionData = files(executionData.findAll { it.exists() })
}
reports {
html.enabled = true // human readable
xml.enabled = true // required by coveralls
}
}
coveralls {
sourceDirs = publishedProjects.sourceSets.main.allSource.srcDirs.flatten()
jacocoReportPath = "${buildDir}/reports/jacoco/jacocoRootReport/jacocoRootReport.xml"
}
tasks.coveralls {
dependsOn jacocoRootReport
}
I believe that the problem is coming from simply adding a task where JacocoReport as a parameter. Any thoughts how I could proceed to have both code coverage, along with building my whitelists correctly?
I have managed to find how to fix the coverage/whitelisting issue. I started stripping away what seemed to be unnecessary code within the subprojects spec, and found that removing everything except the apply plugin:, jacoco, and jacocoTestReport commands yielded both the root Jacoco code coverage, along with the necessary whitelisting. I didn't need to change any of the other code above to get the whitelisting to work.
For reference, subprojects now looks like this:
subprojects {
apply plugin: 'jacoco'
apply plugin: 'kotlin'
jacoco {
toolVersion = jacoco_version
}
//command for generating subproject coverage reports
jacocoTestReport {
reports {
xml.enabled false
csv.enabled false
html.destination file("${buildDir}/jacocoHtml")
}
}
}

gradle jacoco plugin not generate exec files

I've done gradle migration from gradle 3.5 to gradle 4.6. After migration exec files have stopped generated. '/build' folder doesn't contain 'jacoco' folder.
If I run gradle command with -- debug it writes in log :
[org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter]
Skipping task ':common:jacocoTestReport' as task onlyIf is false.
Here is part of gradle script:
subprojects {
apply plugin: 'java'
apply plugin: 'jacoco'
apply plugin: 'idea'
...
jacocoTestReport {
reports {
xml.enabled true
csv.enabled false
}
afterEvaluate {
classDirectories = files(classDirectories.files.collect {
fileTree(dir: it,
exclude: ['**/dto/**', '**/endpoint/**','**/enpoints/**', '**/spring/**',
'**/servlet/**','**/handler/**', '**/jpa/**', '**/filter/**', '**/events/**', '**/dao/**',
'**/exception/**', '**/http/**', '**/jdbc/**', '**/bigquery/**', '**/enums/**',
'**/repository/**', '**/combination/**', '**/datastore/**', '**/cassandra/**',
'**/google/**', '**/exceptions/**', '**/logging/**', '**/JavaGeneratedContext.java', '**/Q*.java'])
})
}
}
test {
enabled = !skipTests
allJvmArgs = [
'-Dfile.encoding=utf-8'
]
useJUnit {
excludeCategories 'com.severn.common.test.IntegrationTest'
}
/*jacoco {
enabled = true
destinationFile = file("$buildDir/jacoco/jacocoTest.exec")
}*/
finalizedBy jacocoTestReport
}
...
}
Make sure:
1) Your debug info is enabled during compile in your top level Gradle file (allprojects { ... } ). See here for more info: Jacoco Unit and Integration Tests coverage - individual and overall
tasks.withType(Compile) {
options.debug = true
options.compilerArgs = ["-g"]
}
2) Try removing the whole Jacoco configuration from the test task (make sure you place the .exec file if generated in the default location where jacocoTestReport task expects it). Make sure test task is running (and not getting excluded somehow). For testing purpose (to narrow down this .exec not getting created issue), you can force jacocoTestReport task to dependOn test task.
tasks.withType(Test) {enabled = true}
3) See latest Gradle 4.6 bundle (tar/zip) for Jacoco examples for a Java single/multi level project to get hint.
PS: Default JaCoCo version upgraded to 0.8.0 See if forcing this version within jacoco block helps.
https://docs.gradle.org/4.6/release-notes.html
The JaCoCo plugin has been upgraded to use JaCoCo version 0.8.0 by default.

jUnit 5 HTML Report using Gradle 4.6 [duplicate]

This question already has an answer here:
Configuration for Gradle 4.7 to generate the HTML report for JUnit 5 tests
(1 answer)
Closed 4 years ago.
I am trying to generate HTML report of JUnit 5 test case.
Here is my Gradle.build file
buildscript {
ext {
springBootVersion = '2.0.0.M3'
}
repositories {
maven { url 'https://zz-artifactory.zzzz.com/artifactory/maven' }
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath 'org.junit.platform:junit-platform-gradle-plugin:1.2.0-M1'
classpath "io.spring.gradle:dependency-management-plugin:1.0.0.RC1"
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'org.junit.platform.gradle.plugin'
apply plugin: "io.spring.dependency-management"
apply from: "CodeCoverage.gradle"
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
dependencies {
compile('org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.2')
compile('org.mybatis.spring.boot:mybatis-spring-boot:1.3.2')
compile('org.mybatis.spring.boot:mybatis-spring-boot-starter-test:1.3.2')
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter-aop')
compile("org.junit.jupiter:junit-jupiter-api:5.2.0-M1")
compile('org.junit.jupiter:junit-jupiter-migrationsupport:5.0.2')
compile("org.junit.jupiter:junit-jupiter-engine:5.2.0-M1")
compile("junit:junit:4.12")
compile("org.junit.vintage:junit-vintage-engine:5.2.0-M1")
compile(group: 'org.junit.platform', name: 'junit-platform-launcher', version: '1.2.0-M1')
compile(group: 'org.junit.platform', name: 'junit-platform-runner', version: '1.2.0-M1')
testCompile('com.h2database:h2:1.4.196')
testCompile('org.mockito:mockito-all:2.0.2-beta')
testCompile('org.mockito:mockito-core:2.8.9')
}
test {
useJUnitPlatform()
}
junitPlatform {
// platformVersion '1.2.0-M1'
filters {
engines {
// include 'junit-jupiter', 'junit-vintage'
// exclude 'custom-engine'
}
tags {
include 'Smoke'
//exclude 'slow'
}
}
}
subprojects {
apply plugin: 'java'
test {
reports.html.enabled = false
}
}
task testReport(type: TestReport) {
destinationDir = file("$buildDir/reports123/allTests")
// Include the results from the `test` task in all subprojects
reportOn subprojects*.test
}
I have used testReport as per
Gradle docs Links
When i run the Gradle task, It runs all the test case, generate XML reprts, but doesnot generate HTML report
In the build log, i see
:testReport NO-SOURCE
any suggestion why it says NO-SOURCE ??
Thanks
You are doing one thing too many. You should either use 'org.junit.platform.gradle.plugin' or test { useJUnitPlatform } but not both.
The standard gradle (html) test reporting will only work with the latter.

Jacoco coverage report of JUnit tests for a Gradle multiproject

I am having difficulty combining Jacoco coverage report for a Gradle multi-project. For simplicity, I have created a simplified version that is structured as follows. I have the example project on GitHub.
+ root
+ common-a
+ common-b
+ project-a
+ project-b
The root, project-a, and project-b are Spring Boot applications. For some context, a project is meant to be a micro-service. Thus, the root project is simply running all micro-services in one process.
Not all projects have unit and/or integration tests. common-a subproject does not have any tests; common-b, project-a, and project-b projects have unit and integration tests; the root project has only integration tests.
The Jacoco coverage reports for subprojects are correct. It is able to combine both unit and integration tests into one cohesive report. However, the root project does not produce the cohesive report correctly.
I have tried a number of solutions with any success. Most of the solutions I found assume that the root project is simply a logical container and only the subprojects has test code. The results of the solutions I tried fall into one of the following three categories.
No Jacoco report generated at all; the build/reports/jacoco directory is missing
Partial Jacoco report for only sources in root project
Full Jacoco coverage report for root and subproject but 0% coverage; it is supposed to be 100% coverage
The following is the current build.gradle file.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.5.RELEASE")
}
}
// settings for all projects
allprojects {
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'jacoco'
group 'io.github.chriszhong'
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
repositories {
jcenter()
}
dependencyManagement {
imports {
mavenBom 'io.spring.platform:platform-bom:2.0.5.RELEASE'
}
}
sourceSets {
integrationTest {
compileClasspath += main.output + test.output
runtimeClasspath += main.output + test.output
java {
srcDir 'src/test-integration/java'
}
resources {
srcDir 'src/test-integration/resources'
}
}
}
configurations {
integrationTestCompile {
extendsFrom testCompile
}
integrationTestRuntime {
extendsFrom testRuntime
}
}
idea {
module {
testSourceDirs += sourceSets.integrationTest.java.srcDirs
testSourceDirs += sourceSets.integrationTest.resources.srcDirs
}
}
task integrationTest(type: Test) {
check {
dependsOn integrationTest
}
testClassesDir sourceSets.integrationTest.output.classesDir
classpath = sourceSets.integrationTest.runtimeClasspath
}
task testReport(type: TestReport) {
dependsOn check
destinationDir file("${reporting.baseDir}/unified/html")
reportOn test, integrationTest
}
task jacocoMerge(type: JacocoMerge) {
dependsOn check
executionData test, integrationTest
// temporary hack to fix a bug requiring that there be at least one test case in each source set for coverage data to be generated;
// it should be if there is at least one test case in any of the source sets
executionData = files(executionData.findAll({ it.exists() }))
}
tasks.withType(Test) {
reports {
html {
destination file("${reporting.baseDir}/${task.name}/html")
}
}
}
tasks.withType(JacocoReport) {
dependsOn jacocoMerge
executionData jacocoMerge.destinationFile
// temporary hack to fix a bug requiring that there be at least one test case in each source set for coverage data to be generated;
// it should be if there is at least one test case in any of the source sets
// executionData = files(executionData.findAll({ it.exists() }))
}
}
apply plugin: 'spring-boot'
version '1.0-SNAPSHOT'
dependencies {
compile project(':project-a')
compile project(':project-b')
testCompile 'junit:junit'
integrationTestCompile 'org.springframework.boot:spring-boot-starter-test'
}
testReport {
dependsOn check, subprojects.testReport
reportOn test, integrationTest, subprojects.test, subprojects.integrationTest
}
jacocoMerge {
dependsOn check, subprojects.jacocoMerge
executionData test, integrationTest, subprojects.jacocoMerge.destinationFile
// temporary hack to fix a bug requiring that there be at least one test case in each source set for coverage data to be generated;
// it should be if there is at least one test case in any of the source sets
executionData = files(executionData.findAll({ it.exists() }))
}
//jacocoTestReport {
// dependsOn jacocoMerge
// executionData test, integrationTest, subprojects.test, subprojects.integrationTest
// executionData jacocoMerge.destinationFile
// temporary hack to fix a bug requiring that there be at least one test case in each source set for coverage data to be generated;
// it should be if there is at least one test case in any of the source sets
// executionData = files(executionData.findAll({ it.exists() }))
// sourceDirectories = files(sourceSets.main.java.srcDirs, subprojects.sourceSets.main.java.srcDirs)
// classDirectories = files(sourceSets.main.output.classesDir, subprojects.sourceSets.main.output.classesDir)
//}
task wrapper(type: Wrapper) {
gradleVersion '2.14'
distributionUrl "https://services.gradle.org/distributions/gradle-${gradleVersion}-all.zip"
}
I have been banging my head at this problem for the past week and is at my wits end. I greatly appreciate any help I can get in resolving this problem.

Resources