jacoco configuration for multi module is not working
Asked Answered
T

3

2

There is something strange going on with my jacoco configuration and I am not able to figure it out. I have visited multiple threads on stack overflow and other platforms and tried many thing, but didn't resolve this issue.

I have setup the java code coverage for multiple modules. This is my project structure

  • ABC

    • module1
  • DEF

    • module1
    • module2
    • module3

    pom.xml

I have configured the jacoco for my DEF maven project. I am only configuring my DEF project. And this is what pom.xml contains

    <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <version>0.8.8</version>
        <executions>
            <execution>
                <goals>
                    <goal>prepare-agent</goal>
                </goals>
            </execution>
            <execution>
                <id>report</id>
                <phase>prepare-package</phase>
                <goals>
                    <goal>report-aggregate</goal>
                </goals>
                <configuration>
                 <outputDirectory>${project.basedir}/target/reports</outputDirectory>
                </configuration>
                </execution>
        </executions>
    </plugin>

Issue: The issue here is, it's generating the code coverage report in each module1, module2 and module3. But the report generated in module1, doesn't contains the code coverage for itself. Meaning, it shows the code coverage for module2 and module3, but it doesn't include module1 report in itself. I don't know what's wrong ?

EDIT : modules in DEF are maven modules and it didn't contains anything related to jacoco.

Any idea or any suggestions ?

Thanks

Trusting answered 7/2, 2023 at 14:58 Comment(3)
You asked me to check this one ... I don't know.Radiolarian
This q does not contain enough information why module1 does not contain coverage code. Please ask on the ASF Maven mailing lists. BTW, you can check if module1 has the correct parent.Nitrogenize
@BenjaminMarwell I have double checked all the relative or absolute paths it's all correct. I am finding it all strange that for other modules it generating the coverage report but for only one module it's not generating.Trusting
O
2

Create one more module as ReportAggregator and move jacoco configuration from parent pom to ReportAggregator pom

Onto answered 22/2, 2023 at 13:18 Comment(3)
Shouldn't jacoco configuration be in parent pom ?Trusting
This way it indeed solved my problem. But I ran into one more issue after that, which I was able to resolve on my own, which I will post as an answer for future SO followers. But I have no idea why do we need to create another module for aggregating the code coverages. Is this some kind of bug from jacoco or is this the limitation we have ?Trusting
can you please respond to my above queries ?Trusting
T
2

Thank you @Sarang for the response. It did resolve my problem, but after that I ran into one more issue and that is for one of my module it was not generating the jacoco.exec file. After some investigation it seems the problem was with <argLine> tag. In one of my module I was using this tag and somehow this was overridden.

So what I did is I pre append the argLine before this and it resolve my issue

<configuration>
    <argLine>${argLine} -XX:PermSize=256m -XX:MaxPermSize=1048m</argLine>
</configuration>
Trusting answered 23/2, 2023 at 14:29 Comment(0)
D
0

You can try to merge unit test and instrument test from app module :

task jacocoUiTestReportAllModules(type: JacocoReport, dependsOn: ['testDebugUnitTest', 'createDebugCoverageReport']) {
    group "Reports"
    description "Generate Jacoco Instrumented Tests coverage reports for all modules"
    reports {
        xml.enabled = true
        html.enabled = true
        html.destination file("${rootProject.buildDir}/coverage-report")
    }
    def javaClasses = []
    def kotlinClasses = []
    def javaSrc = []
    def kotlinSrc = []
    def execution = []
    def fileFilter = ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*', '**/*Test*.*', 'android/**/*.*']
    rootProject.subprojects.each { proj ->
        javaClasses << fileTree(dir: "$proj.buildDir/intermediates/javac/debug", excludes: fileFilter)
        kotlinClasses << fileTree(dir: "$proj.buildDir/tmp/kotlin-classes/debug", excludes: fileFilter)
        javaSrc << "$proj.projectDir/src/main/java"
        kotlinSrc << "$proj.projectDir/src/main/kotlin"
        execution << fileTree(dir: proj.buildDir, includes: [    'jacoco/testDebugUnitTest.exec',
                'outputs/code_coverage/debugAndroidTest/connected/**/*.ec'])
    }
    getSourceDirectories().setFrom(files([javaSrc, kotlinSrc]))
    getClassDirectories().setFrom(files([javaClasses, kotlinClasses]))
    getExecutionData().setFrom(execution)

    doLast() {
        print "file://${reports.html.destination}/index.html"

    }
}
Decumbent answered 12/5, 2023 at 3:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.