Я строю сервер SonarQube 6.2, который уже анализирует мои проекты Java 8/Gradle 3.3. При добавлении JaCoCo к многомодульных Gradle проекта, я понял, что SonarQube является измерение покрытия кода на «на-модуле» основе:SonarQube: Покрытие неполное по проекту с многомодульным градиентом с JaCoCo
Если класс находится в модуле A
и тест для этого класса находится в модуле B
, SonarQube показывает, что класс не включен.
Я хочу измерить покрытие кода по всем модулям, а не по модулю. Как мне это достичь?
Есть много похожих вопросов, но нет полезных ответов, хотя ситуация для меня довольно распространена. Например, Дженкинс делает это по умолчанию.
Я решил построить blueprint on github, чтобы уточнить проблему.
Основной build.gradle
состоит из
plugins { id "org.sonarqube" version "2.2.1" }
subprojects {
apply plugin: 'java'
apply plugin: 'jacoco'
repositories { mavenCentral() }
dependencies { testCompile "junit:junit:4.12" }
}
modA/build.gradle
пуст.
Состоит из 3 классов: TestedInModA
, TestedInModATest
и TestedViaModB
.
modB/build.gradle
просто объявляет зависимость к modA
:
dependencies { compile project(':modA') }
Он содержит только один класс: TestedViaModBTest
, тестирование класса TestedViaModB
, расположенный в modA
.
Мой (частный) экземпляр Jenkins показывает 100% -ый охват для двух классов, включенных, пока SonarQube говорит, что только класс TestedInModA
(который протестирован в его собственном модуле) покрыт.
Как изменить процесс сборки, чтобы увидеть «кросс-модульное покрытие» в SonarQube?
Я хотел бы обновить свой проект, чтобы будущие посетители этого вопроса могли найти рабочий пример.
Мой рабочий раствор (спасибо @Godin)
добавить следующее в
subprojects
закрытияtasks.withType(Test) { // redirect all coverage data to one file // ... needs cleaning the data prior to the build to avoid accumulating coverage data of different runs. // see `task cleanJacoco` jacoco { destinationFile = file("$rootProject.buildDir/jacoco/test.exec") } }
добавить
task cleanJacoco(dependsOn: 'clean') { delete "$buildDir/jacoco" }
снаружиsubprojects
закрытие.
Thanks @Godin; «destinationFile», похоже, работает, но как я могу последовательно удалить старые данные exec перед новым запуском? Использование задачи 'jacocoMerge', похоже, имеет тот же результат (... кроме того, что хранятся исходные файлы' * .exec'), но файл автоматически восстанавливается следующей сборкой. Однако мне не удалось интегрировать это в нужное место (см. Комментарий в главном 'build.gradle' в проекте github). –
'sonar.jacoco.reportPaths' выглядит многообещающим, но, похоже, его игнорируют (покрытие по-прежнему 50%, logfile говорит' Property 'sonar.jacoco.reportPath' устарел. Вместо этого используйте 'sonar.jacoco.reportPaths'.) I обновил основную 'build.gradle' с моей попыткой. –
@sk_dev о первом вопросе с первого комментария - почему бы не поместить его в каталог сборки, так что он будет очищен на './gradlew clean build' – Godin