Генерация отчета о покрытии JaCoCo путем выполнения приложения JAR - PullRequest
0 голосов
/ 08 февраля 2020

Я разрабатываю консольное приложение Java (CLI) и пытаюсь написать несколько тестов черного ящика, выполнив эту программу, проверив вывод и сравнив его с ожидаемым (используя JUnit). Все в порядке, но я не могу получить отчет о покрытии кода от JaCoCo.

Конфигурация JaCoCo и JUnit в моем файле build.gradle:

...

plugins {
    id 'jacoco'
}

...

dependencies {
    ...

    testCompile('org.junit.jupiter:junit-jupiter:5.5.2')
}

test {
    useJUnitPlatform()
}

jacoco {
    toolVersion = "0.8.5"
    reportsDir = file("$buildDir/reports")
}

jacocoTestReport {
    reports {
        xml.enabled true
        csv.enabled false
        xml.destination file("${buildDir}/coverage.xml")
    }

    getExecutionData().setFrom("$buildDir/jacoco/test.exec")
}

В тестах я делаю это:

String command = "java -javaagent:libs/jacocoagent.jar=destfile=build/jacoco/test.exec -jar build/libs/myapp.jar";
Process process = Runtime.getRuntime().exec(command);
process.waitFor();

InputStream inputStream = process.getInputStream();

byte[] b = new byte[inputStream.available()];

String cliOutput = new String(b);

После выполнения теста файлы build/jacoco/test.exec и build/coverage.xml создаются, но не содержат никакой информации о покрытии.

Для простых юнит-тестов покрытие генерируется, но не включает покрытие от выполнения всей программы, как указано выше.

UPD: Также я попробовал другой способ запустить JAR:

List<String> args = new ArrayList<>();

args.add("java");
args.add("-javaagent:libs/jacocoagent.jar=destfile=build/jacoco/test.exec");
args.add("-jar");
args.add(this.getCLiPath());
args.add(command);

ProcessBuilder builder = new ProcessBuilder(args.toArray(new String[0]));
Process process = builder.start();

Но это не помогло, тот же результат - нет покрытия от выполнения JAR.

UPD 2: Я только что обнаружил, что данные выполнения собираются в файл .exec.

Но эти данные пропускаются при создании отчета (в задаче Gradle jacocoTestReport) с сообщениями об ошибках [ant:jacocoReport] Execution data for class ... does not match..

Это мои данные выполнения из файла JAR, но по какой-то причине они пропущены в отчете.

1 Ответ

0 голосов
/ 09 февраля 2020

Наконец-то я нашел решение, поэтому мне нужно документировать это.

Ошибка была связана с classID. Эта концепция подробно описана на docs-сайте JaCoCo - Идентификаторы класса . В скомпилированном приложении идентификаторы классов различаются, и JaCoCo не может справиться с этим.

Подробнее в этом вопросе . Этот ответ помог мне с ошибками ant:jacocoReport.

Кроме того, мне нужно было исправить мой CI / CD. Я использую Azure DevOps Pipelines.

Моя задача Gradle в конвейере:

- task: Gradle@2
    displayName: 'Gradle build, tests, code coverage report'
    inputs:
      gradleWrapperFile: 'gradlew'
      gradleOptions: '-Xmx3072m'
      javaHomeOption: 'JDKVersion'
      jdkVersionOption: '1.8'
      jdkArchitectureOption: 'x64'
      publishJUnitResults: true
      testResultsFiles: '**/TEST-*.xml'
      tasks: 'doJacocoOfflineInstrumentation buildCliJar test jacocoTestReport'
...