Home > Software engineering >  Unable to get report from Jacoco gradle Kotlin project on SonarCloud
Unable to get report from Jacoco gradle Kotlin project on SonarCloud

Time:11-11

Right, so I have a Kotlin Gradle project with the framework SpringBoot. The project is on GitHub and our CI system is Circle CI.

At the build.gradle.kts file we have the following configs:


sonarqube {
    properties {
        property("sonar.projectKey", "Creditas_recupera-gateway")
        property("sonar.organization", "creditas-fintech")
        property("sonar.host.url", "https://sonarcloud.io")
        property(
            "sonar.coverage.jacoco.xmlReportPaths",
            "$buildDir/reports/jacoco/jacocoTestReport/jacocoTestReport.xml"
        )
    }
}

fun ignorePackagesInJacocoReport(classDirectories: ConfigurableFileCollection) {
    classDirectories.setFrom(
        files(
            classDirectories.files.map {
                fileTree(it).apply {
                    exclude(
                        "**/company/**/*.java",
                        "**/company/**/*.kts",
                        "**/company/commons/**",
                        "**/company/**/config/**",
                        "**/company**/configuration/**",
                        "**/company/**/requests/**",
                        "**/company/**/responses/**",
                        "**/company/**/dto/**",
                        "**/company/**/infrastructure/scripts/**"
                    )
                }
            }
        )
    )
}


tasks.jacocoTestReport {
    sourceSets(sourceSets.main.get())
    executionData(fileTree(project.rootDir.absolutePath).include("**/build/jacoco/*.exec"))

    reports {
        xml.required.set(true)
        html.required.set(true)
        xml.outputLocation.set(File("$buildDir/reports/jacoco/jacocoTestReport/jacocoTestReport.xml"))
        html.outputLocation.set(layout.buildDirectory.dir("$buildDir/reports/jacoco"))
    }

    ignorePackagesInJacocoReport(classDirectories)
}

Our config.yml used by Circle CI is like the following:

version: 2.1

orbs:
  docker: circleci/[email protected]

jobs:
  unit_test:
   
    steps:
      - run:
          name: Run tests
          command: gradle test -i

      - run:
          name: Save test results
          command: |
            mkdir -p ~/junit/
            find . -type f -regex ".*/build/test-results/.*xml"
            find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} ~/junit/ \;
          when: always

      - persist_to_workspace:
          root: ~/
          paths:
            - project-folder/build/jacoco

  coverage:
    steps:
      - run: ./gradlew dependencies build -x test -x detekt
      - run:
          name: Run coverage report
          command: ./gradlew jacocoTestReport

      - persist_to_workspace:
          root: ~/
          paths:
            - recupera-gateway/build/reports/jacoco

  sonarqube:
    steps:
      - restore_cache:
          keys:
            - app-dependencies-{{ checksum "build.gradle.kts" }}

      - run: ./gradlew dependencies build -x test -x detekt

      - save_cache:
          paths:
            - ~/.gradle
          key: app-dependencies-{{ checksum "build.gradle.kts" }}

      - attach_workspace:
          at: ~/

      - run:
          name: Run sonar analysis
          command: ./gradlew sonarqube


workflows:
  version: 2.1
      - unit_test
      - coverage:
          requires:
            - unit_test
      - sonarqube:
          requires:
            - coverage

Locally, running:

./gradlew jacocoTestReport

returns:

Local test report

However, on SonarCloud, is the following: SonarCloud report

Note that excluded files in Jacoco are present, and the total coverage is completely different. In SonarCloud General Settings, I am passing JacocoTestReport.xml path to the file:

enter image description here

So, first, I have a question: Does SonarCloud have the capacity to calculate the coverage by itself? Because it looks like it is taking the coverage results from somewhere else.

And second: How do I make Jacoco's Coverage Report match with SonarCloud's?

Note that I have omitted many information for security and privacy reasons. If any crucial information is missing, please ask and I will see if it can be provided. Also, it might sound like a duplicate, however other topics found does not have a solution for the problem.

CodePudding user response:

What happened is that, first of all, SonarCloud is unable to check if a file is being ignored or not from Jacoco's report, so it assumes it is 0% coverage. To solve this issue, it would be necessary to add the excluded files to Jacoco as well.

Another thing about the difference between Jacoco's coverage and SonarCloud's is that Jacoco also takes under consideration the instruction coverage, which is not represented on SonarCloud.

For a more complete answer I suggest to see this post on Sonar's forum here, all credits to that page.

  • Related