[英]Android - Jacoco does not generate xml report properly
我們已經將 JaCoCo 插件集成到我們的 Android 項目中,用於通過 SonarQube 測量代碼覆蓋率。但是,它無法測量。 因為 SonarQube 期望覆蓋率報告為 XML 格式。 我們將自定義jacocoTestReport任務添加到 build.gradle(module)。 它生成一個 xml 文件,但不包含任何覆蓋信息。 你遇到過這樣的問題嗎? 如果有,你有什么解決辦法嗎?
build.gradle(根)
classpath "org.jacoco:org.jacoco.core:0.8.5"
build.gradle(模塊)
apply plugin: 'jacoco'
...
task jacocoTestReport(type: JacocoReport, dependsOn: ['testDebugUnitTest']) {
reports {
xml.enabled = true
html.enabled = true
}
def fileFilter = ['**/R.class',
'**/R$*.class',
'**/BuildConfig.*',
'**/Manifest*.*',
'**/*Test*.*',
'android/**/*.*']
def debugTree = fileTree(dir: "${buildDir}/intermediates/classes/debug", excludes: fileFilter)
def mainSrc = "${project.projectDir}/src/main/java"
getSourceDirectories().setFrom(files([mainSrc]))
getClassDirectories().setFrom(files([debugTree]))
getExecutionData().setFrom(fileTree(dir: "$buildDir", includes: [
"jacoco/testDebugUnitTest.exec",
"outputs/code-coverage/connected/*coverage.ec"
]))
Output:
Baseline: AGP 7.1.2 +, jacoco 0.88, hilt 2.42,很多你要更新jacoco.gradle文件。
apply plugin: 'jacoco'
jacoco {
toolVersion = '0.8.7'
}
task jacocoTestReport { self ->
build.dependsOn self
}
//Use this method to generate the HTML and XML coverage report files for
Unit and UI test cases
android.testVariants.all {
def variant = it.testedVariant
def variantName = variant.name.capitalize()
def unitTestTask = "test${variantName}UnitTest"
def androidTestCoverageTask = "create${variantName}CoverageReport"
tasks.create(name: "jacoco${name}TestReport", type: JacocoReport)
{ self ->
group = 'Reporting'
description = "Generates Jacoco coverage reports on the
${variant.name} variant"
reports {
xml.enabled(true)
html.enabled(true)
}
def excludes = [
// data binding
'android/databinding/**/*.class',
'**/android/databinding/*Binding.class',
'**/android/databinding/*',
'**/androidx/databinding/*',
'**/BR.*',
// android
'**/R.class',
'**/R$*.class',
'**/BuildConfig.*',
'**/Manifest*.*',
'**/*Test*.*',
'android/**/*.*',
// butterKnife
'**/*$ViewInjector*.*',
'**/*$ViewBinder*.*',
// dagger
'**/*_MembersInjector.class',
'**/Dagger*Component.class',
'**/Dagger*Component$Builder.class',
'**/*Module_*Factory.class',
'**/di/module/*',
'**/*_Factory*.*',
'**/*Module*.*',
'**/*Dagger*.*',
'**/*Hilt*.*',
// kotlin
'**/*MapperImpl*.*',
'**/*$ViewInjector*.*',
'**/*$ViewBinder*.*',
'**/BuildConfig.*',
'**/*Component*.*',
'**/*BR*.*',
'**/Manifest*.*',
'**/*$Lambda$*.*',
'**/*Companion*.*',
'**/*Module*.*',
'**/*Dagger*.*',
'**/*Hilt*.*',
'**/*MembersInjector*.*',
'**/*_MembersInjector.class',
'**/*_Factory*.*',
'**/*_Provide*Factory*.*',
'**/*Extensions*.*',
// sealed and data classes
'**/*$Result.*',
'**/*$Result$*.*'
]
def javaClasses = fileTree(dir:
variant.javaCompileProvider.get().destinationDir,
excludes: excludes)
def kotlinClasses = fileTree(dir: "${buildDir}/tmp/kotlin-
classes/${variant.name}",
excludes: excludes)
classDirectories.setFrom(files([
javaClasses,
kotlinClasses
]))
def variantSourceSets = "${project.projectDir}/src/main/java"
sourceDirectories.setFrom(project.files(variantSourceSets))
def androidTestsData = fileTree(dir:
"${buildDir}/outputs/code_coverage/${variant.name}AndroidTest/connected/",
includes: ["**/*.ec"])
executionData(files([
"$project.buildDir/outputs/unit_test_code_coverage/${variant.name}UnitTest/test
${variantName}UnitTest.exec",
androidTestsData
]))
dependsOn unitTestTask, androidTestCoverageTask
jacocoTestReport.dependsOn self
}
}
由於 AGP 正在更新,構建目錄中的路徑已更改。
//替換這段代碼
executionData.from = fileTree(dir: buildDir, includes: [
"jacoco/test${variantName}UnitTest.exec",
"/outputs/code_coverage/${variant.name}AndroidTest/connected/*coverage.ec"
])
//到這段代碼
def androidTestsData = fileTree(dir: "${buildDir}/outputs/code_coverage/${variant.name}AndroidTest/connected/", includes: ["**/*.ec"])
executionData(files([
"$project.buildDir/outputs/unit_test_code_coverage/${variant.name}UnitTest/test${variantName}UnitTest.exec",
androidTestsData
]))
你的 gradle 版本是多少? gradle 6.4+ Z 5E056C500A1C4B6A7110B50D807BADE5Z 似乎存在一些問題://github.com/gradle/gradle/issues/14132
經過一番谷歌搜索,我終於解決了這個問題。 源和 class 目錄的路徑不正確。 正確的路徑應該是這樣的:
def javaClasses = fileTree(dir: variant.javaCompileProvider.get().destinationDir,
excludes: fileFilter)
def kotlinClasses = fileTree(dir: "${buildDir}/tmp/kotlin-classes/${variantName}",
excludes: fileFilter)
classDirectories.setFrom(files([
javaClasses,
kotlinClasses
]))
def variantSourceSets = variant.sourceSets.java.srcDirs.collect { it.path }.flatten()
sourceDirectories.setFrom(project.files(variantSourceSets))
問候,
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.