Gradle: как создать отчет о покрытии для теста интеграции с помощью jacoco

Я новичок в gradle. Я использую приведенный ниже код. Но он генерирует покрытие для случаев unit test. Но это не создавало для тестовых случаев интеграции. У меня есть тестовые классы в пакете src/test/java.

test {
    dependsOn jettyRunWar
    ignoreFailures true
    finalizedBy jettyStop
}

apply plugin: 'jacoco'

jacocoTestReport {
    group = "Reporting"
    description = "Generate Jacoco coverage reports after running tests."
    additionalSourceDirs = files(sourceSets.main.allJava.srcDirs)
}

Ответ 1

Используя Gradle 5.4.1 (а теперь и 5.5.1), я смог получить отчет после любого тестового задания, в настоящее время у меня есть задачи test и integrationTest.

РЕДАКТИРОВАТЬ2: решение то же самое, я просто подправил

  • назначение отчетов для использования jacoco.reportsDir,
  • теперь для executeData используется tasks.withType(Test), а не просто [test, integrationTest]
  • настройка executionData выполняется в блоке doFirst вместо doLast

РЕДАКТИРОВАТЬ: После просмотра документации JacocoReport, есть вариант JacocoReport: executeData, который непосредственно принимает задачи Gradle. Это работает, потому что плагин JaCoCo добавляет расширение JacocoTaskExtension ко всем задачам типа Test. Который тогда меньше подвержен ошибкам. Задачей отчета становится:

jacocoTestReport {
    doFirst {
        // The JaCoCo plugin adds a JacocoTaskExtension extension to all tasks of type Test.
        // Use task state to include or not task execution data
        // https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/TaskState.html
        executionData(tasks.withType(Test).findAll { it.state.executed })
    }

    reports {
        xml.enabled true
        xml.destination(file("${jacoco.reportsDir}/all-tests/jacocoAllTestReport.xml"))
        html.enabled true
        html.destination(file("${jacoco.reportsDir}/all-tests/html"))
    }
}

И тот же прием можно применить к задаче sonarqube:

sonarqube {
    group = "verification"
    properties {
        // https://jira.sonarsource.com/browse/MMF-1651
        property "sonar.coverage.jacoco.xmlReportPaths", jacocoTestReport.reports.xml.destination
        properties["sonar.junit.reportPaths"] += integrationTest.reports.junitXml.destination
        properties["sonar.tests"] += sourceSets.integrationTest.allSource.srcDirs
        // ... other properties
    }
}

Старый, но очень рабочий ответ. Также, используя приведенные выше сведения (что задача Test расширена JacocoTaskExtension), можно заменить ручную настройку file executionData на test.jacoco.destinationFile и integrationTest.jacoco.destinationFile.

// Without it, the only data is the binary data, 
// but I need the XML and HTML report after any test task
tasks.withType(Test) {
    finalizedBy jacocoTestReport
}

// Configure the report to look for executionData generated during the test and integrationTest task
jacocoTestReport {
    executionData(file("${project.buildDir}/jacoco/test.exec"),
                  file("${project.buildDir}/jacoco/integrationTest.exec"))
    reports {
        // for sonarqube
        xml.enabled true
        xml.destination(file("${project.buildDir}/reports/jacoco/all-tests/jacocoAllTestReport.xml"))
        // for devs
        html.enabled true
        html.destination file("${project.buildDir}/reports/jacoco/all-tests/html")
    }
}


sonarqube {
    group = "verification"
    properties {
        // https://jira.sonarsource.com/browse/MMF-1651
        property "sonar.coverage.jacoco.xmlReportPaths", ${project.buildDir}/test-results/integrationTest"
        properties["sonar.junit.reportPaths"] += "${project.buildDir}/test-results/integrationTest"
        properties["sonar.tests"] += sourceSets.integrationTest.allSource.srcDirs
        // ... other properties
    }
}

project.tasks["sonarqube"].dependsOn "jacocoTestReport"

Ответ 2

Похоже, вам нужно сказать, что build.gradle - это где ваши тестовые тесты Intergration (т.е. папка, содержащая эти ИТ-тесты) с использованием sourceSets. В моем случае у меня есть источник в src/java (вместо src/main/java - gradle default).. мои юнит-тесты (Junit) в папке test/java и мои интеграционные тесты в папке src/java-test.

sourceSets {
   main {
      java {
         srcDir 'src/java'
      }
   }
   test {
      java {
         srcDir 'test/java'
      }
      resources {
         srcDir 'test/resources'
         srcDir 'conf'
      }
   }
   integrationTest {
      java {
         srcDir 'src/java-test'
      }
   }
}

Затем у меня есть задача IntegrationTest как... которую вы можете настроить, поскольку у вас может не быть cleanTest (пользовательская задача, которую я создал), поэтому вы можете игнорировать это, зависит от... я думаю, в вашем случае вы будете использовать что-то вроде jettyStart, поскольку вы используете это для ИТ-тестов (начиная контейнер для запуска ИТ-тестов, а затем финализированный вариант для остановки причала.. плагин причала)

task integrationTest( type: Test, dependsOn: cleanTest ) {
   jacoco {
      //destinationFile = file("$buildDir/jacoco/jacocoTest.exec")
      destinationFile = file("$buildDir/jacoco/integrationTest.exec")
      //classDumpFile = file("$buildDir/jacoco/classpathdumps")
      classDumpFile = file("$buildDir/classes/integrationTest")
   }
   testClassesDir = sourceSets.integrationTest.output.classesDir
   classpath = sourceSets.integrationTest.runtimeClasspath
}

СМОТРИТЕ этот пост для более подробной структуры вывода и script, которые у меня есть на моем конце. Я получаю .exec для обоих модульных тестов (test.exec) и ИТ-тестов intergrationTest.exec.. но я не получаю отчеты jacoco.xml/jacocoHtml для обоих тестов. Я также обнаружил, что если я запустил "gradle чистая сборка" (включающая вызов "тестовой" задачи) и "gradle clean build integrationTest", а затем перезаписывает данные единичных тестов в папке build/test-results и сборка/отчеты/тесты.

Якоби и интеграция Тесты - индивидуальные и общие

ПРИМЕЧАНИЕ. В моем случае jacocoTestReport определен в глобальной папке gradle init.d в одном из обычных файлов gradle. Это поможет нам не включать один и тот же код во все/на уровне проекта build.gradle.