Как создать сводный отчет Jacoco для многомодульного проекта?

#android #gradle #sonarqube #jacoco #multi-module

Вопрос:

Я уже несколько дней ищу решение для объединения нескольких Jacoco отчетов для многомодульного проекта Android, чтобы отправить их Sonarcloud сразу. Я уже проверил тонны сообщений Stackoverflow и других вещей, таких как блоги, репозитории Github, форум Gradle и т. Д., Но, К сожалению, ни одно из решений не работает для меня.

Я был бы очень признателен, если бы кто-нибудь здесь поделился со мной примером проекта или фрагментом кода.

 Gradle version: 7.0.2
Kotlin version: 1.5.21
JDK: 11
 

Приведенный ниже фрагмент кода также не работает для меня

 /**
 *  Root task that generates an aggregated Jacoco test coverage report for all sub-projects
 */
task jacocoFullReport(type: JacocoReport, group: 'Coverage reports') {
    group = 'Reporting'
    description = 'Generates an aggregate report from all subprojects'

    tasks.withType(Test) {
        ignoreFailures true
    }

    def projects = subprojects

    //noinspection GrUnresolvedAccess
    dependsOn(projects.jacocoReport)

    final source = files(projects.jacocoReport.sourceDirectories)

    additionalSourceDirs.setFrom source
    sourceDirectories.setFrom source

    classDirectories.setFrom files(projects.jacocoReport.classDirectories)
    executionData.setFrom files(projects.jacocoReport.executionData)

    reports {
        html {
            enabled true
            destination file('build/reports/jacoco/html')
        }
        csv {
            enabled true
            destination file('build/reports/jacoco/jacocoFullReport.csv')
        }
    }

    doFirst {
        //noinspection GroovyAssignabilityCheck
        executionData.setFrom files(executionData.findAll { it.exists() })
    }
}
 

Комментарии:

1. Плагин org.sonarqube Gradle выполняет итерацию по всем подпроектам и отправляет все XML-отчеты JaCoCo. Зачем вам нужно их объединять?

2. @agabrys да, именно так, но я просто хотел вместо этого предоставить один файл. Но ты имеешь в виду, что ниже одного должно быть хорошо, верно? sonarqube { properties { property "sonar.coverage.jacoco.xmlReportPaths", fileTree(dir: "$projectDir", includes: ["**/reports/jacoco/*/jacocoTestReport.xml"]).files.join(", ") } }

3. Удалите sonar.coverage.jacoco.xmlReportPaths имущество. Его значение по умолчанию делает именно то, что вам нужно. Как правило, вам не следует устанавливать какие-либо свойства СонарСканера, если вам не нужно изменять поведение по умолчанию.

4. По умолчанию плагин JaCoCo Gradle создает отчеты в build/reports/jacoco/<taskName>/jacocoTestReport.xml файле. SonarScanner по умолчанию настраивается sonar.coverage.jacoco.xmlReportPaths на проверку build/reports/jacoco/test/jacocoTestReport.xml . Проверьте build.gradle , не заставляет ли вас создавать отчеты Android JaCoCo в другом месте. Если да — то удалите его и используйте значения по умолчанию. Если нет — вы можете перейти на использование стандартного местоположения.

5. Спасибо, я заставил свою задачу создавать отчеты для Android модулей в том же месте, что и другие Kotlin модули, и удалил свойство. Похоже, все работает так же, как и раньше.

Ответ №1:

Вот рабочий пример создания сводного отчета jacoco: https://github.com/SurpSG/jacoco-gradle-plugin-merge-coverage

 task jacocoRootReport(type: JacocoReport, group: 'Coverage reports') {
    description = 'Generates an aggregate report from all subprojects'
    dependsOn(subprojects.test)

    additionalSourceDirs.from = files(subprojects.sourceSets.main.allSource.srcDirs)
    sourceDirectories.from = files(subprojects.sourceSets.main.allSource.srcDirs)
    classDirectories.from = files(subprojects.sourceSets.main.output)
    executionData.from = files(subprojects.jacocoTestReport.executionData)

    reports {
        html.enabled true
    }
}
 

Комментарии:

1. спасибо за ответ, но у меня это не работает. Я получаю ошибку ниже: Could not get unknown property 'test' for project ':app' of type org.gradle.api.Project.