gradle jacoco plugin not generate exec files - gradle

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.

Related

The legacy `maven` plugin was removed in Gradle 7. Please use the `maven-publish` plugin in instead

I´m trying to run a project using gradle but I´m getting the following error.
FAILURE: Build failed with an exception.
* Where:
Build file 'D:\ISEP\ODSOFT\Projects\odsoft-21-22-nmb-g311\odsoft-21-22-nmb-g311\project\build.gradle' line: 4
* What went wrong:
An exception occurred applying plugin request [id: 'fr.putnami.gwt', version: '0.4.0']
> Failed to apply plugin class 'org.gradle.api.plugins.MavenPlugin'.
> The legacy `maven` plugin was removed in Gradle 7. Please use the `maven-publish` plugin instead. See https://docs.gradle.org/7.2/userguide/publishing_maven.html#publishing_maven for details
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
The command I´m using to run project is gradle gwtRun.
I leave below my gradle bulid file
plugins {
id "fr.putnami.gwt" version "0.4.0"
id "maven-publish"
}
apply plugin: 'war'
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'jacoco'
apply plugin: 'maven-publish'
//Java version compatibility to use when compiling Java source.
sourceCompatibility = 1.8
//Java version to generate classes for.
targetCompatibility = 1.8
//Script Version
version = '1.0'
repositories {
mavenCentral()
}
dependencies {
//testCompile 'junit:junit:4.12'
//testCompile group: 'junit', name: 'junit', version: '4.12'
testImplementation group: 'junit', name: 'junit', version: '4.12'
testImplementation 'org.easymock:easymock:2.5.2'
testImplementation 'com.google.gwt:gwt-dev:2.8.1'
implementation 'net.sourceforge.plantuml:plantuml:8001'
//compile 'net.sourceforge.plantuml:plantuml:8001'
}
javadoc {
options.addStringOption("sourcepath", "")
}
// If we woant to use the default ant build inside gradle
// ant.importBuild "build.xml"
putnami{
module 'pt.isep.cms.Showcase'
//module 'com.google.gwt.sample.contacts.Contacts'
/** add gwt nature on eclipse project. require apply plugin: 'eclipse' to work. default : false*/
googlePluginEclipse = true
gwtVersion='2.8.1'
compile {
sourceLevel = '1.8'
}
jetty {
/** enable debugging. */
debugJava = true
/** debug port to listen. */
debugPort = 8000
/** wait for debugger attachment. */
debugSuspend = false
}
}
// Jacoco
jacocoTestReport {
reports {
xml.enabled false
csv.enabled false
}
}
// This task generates the coverage report for the integration tests.
// Notice that it only includes data about the server code sice Jaccoco is not able to get data about cliente code that is transpiled to javascript
task jacocoIntegrationReport(type: org.gradle.testing.jacoco.tasks.JacocoReport) {
sourceSets sourceSets.main
executionData = files("${buildDir}/jacoco/integrationTest.exec")
reports {
html.enabled = true
xml.enabled = false
csv.enabled = false
}
}
// Integration Tests
task integrationTest(type: Test) {
filter {
//all GWT unit tests, by naming convention
includeTestsMatching "*GWTTest*"
}
jacoco {
append = true
enabled = true
//classDumpFile = file("${buildDir}/jacoco/classpathdumps")
excludes = ["com/steadystate/**"]
}
// These Properties are required to run gwt integration tests
systemProperties['gwt.args'] = "-devMode -logLevel WARN -war www-test"
}
tasks.withType(Test) {
reports.html.destination = file("${reporting.baseDir}/${name}")
}
// Unit Tests
test {
filter {
//all JRE unit tests, by naming convention
includeTestsMatching "*JRETest*"
}
jacoco {
append = true
enabled = true
//classDumpFile = file("${buildDir}/jacoco/classpathdumps")
}
}
From what I understood the plugin maven was removed in the version 7 of gradle. Is this sentence correct? Or is the putnami plugin that was removed?
What should I do to make it to work?
The plugin fr.putnami.gwt applies the maven plugin internally:
https://github.com/Putnami/putnami-gradle-plugin/blob/master/src/main/java/fr/putnami/gwt/gradle/PwtLibPlugin.java#L47
Therefore, fr.putnami.gwt is not compatible with Gradle 7.
As stated in the README in the repo:
A fork of it that is still supported and has a newer release is available at https://github.com/esoco/gwt-gradle-plugin. Please use the new version if you need GWT support for Gradle.
So, then the following should work:
plugins {
id "de.esoco.gwt" version "1.1.1"
}

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
}

jacocoRootReport only shows coverage from last project of multi-project gradle build

I'm upgrading my Gradle 4 multi-project setup to Gradle 6. I've followed instructions here:
https://stackoverflow.com/a/56181389
and I've bumped the jacoco version to 0.8.5. Right now the only problem is that the human-readable coverage report seems to be missing most of the coverage data that it was showing under the old version. It seems that the coverage report is only reflecting the last (most recently tested) project. It used to work fine under Gradle 4. I'm using Java 8.
I ran the gradle build using --debug, and I notice that the test.exec file is deleted repeatedly, once for each subproject that has tests. I think this is the problem, but I don't know how to prevent deletion of this file.
2020-04-16T09:16:21.048-0600 [DEBUG] [org.gradle.internal.file.impl.DefaultDeleter] Deleting /Users/bishop/dev/aep/edge-profile-lookup-target/build/jacoco/test.exec
Can someone please help me fix this so that all of the coverage (from each of the tests which ran against each of the sub projects) appear in a single coverage report?
Here are the parts of the main build.gradle file that seem relevant:
buildscript {
ext {
jacocoVersion = '0.8.5'
...
}
...
}
allprojects {
...
apply plugin: 'jacoco'
...
}
subprojects {
tasks.withType(Test) {
// redirect all coverage data to one file
jacoco {
destinationFile = file("$rootProject.buildDir/jacoco/test.exec")
}
}
jacoco {
toolVersion = jacocoVersion
}
jacocoTestReport {
additionalSourceDirs.from = files(sourceSets.main.allSource.srcDirs)
sourceDirectories.from = files(sourceSets.main.allSource.srcDirs)
classDirectories.from = files(sourceSets.main.output.collect {
fileTree(dir: it, exclude: project.properties['BUILD_COVERAGE_EXCLUSIONS'].tokenize(','))
})
reports {
html.enabled = true
xml.enabled = true
csv.enabled = false
}
}
}
task jacocoRootReport(type: JacocoReport) {
dependsOn = subprojects.test
additionalSourceDirs.from = files(subprojects.sourceSets.main.allSource.srcDirs)
sourceDirectories.from = files(subprojects.sourceSets.main.allSource.srcDirs)
classDirectories.from = files(subprojects.jacocoTestReport.classDirectories)
executionData.from = files(subprojects.jacocoTestReport.executionData)
reports {
html.enabled = true
xml.enabled = true
csv.enabled = false
}
onlyIf = {
true
}
doFirst {
executionData.from = files(executionData.findAll {
it.exists()
})
}
}
...
apply plugin: 'jacoco'
configurations.create("jacoco")
configurations {
jacoco
}
dependencies {
jacocoAnt group: 'org.jacoco', name: 'org.jacoco.ant', version: jacocoVersion
jacocoAnt group: 'org.ow2.asm', name: 'asm', version: asmVersion
}
task copyRuntimeLibs(type: Copy) {
from configurations.jacoco
into "$rootProject.buildDir/libs"
}
build.dependsOn copyRuntimeLibs
The following:
jacoco {
destinationFile = file("$rootProject.buildDir/jacoco/test.exec")
}
configures Jacoco to always use the same output file.
So the issue is most likely that more recent Gradle versions work on separating colliding outputs.
I would recommend looking at the recently published sample on how to setup Jacoco in a multi project instead of attempting to rely on colliding outputs.

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 skipping jacoco coverage plugin

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
}

Resources