先贴一下测试代码最近要在android项目中引入jacoco代码检测,想要先在自己的项目里跑一下,但是太菜了,调了好久,把中间遇到的主要问题记录一下吧。
apply plugin: 'jacoco'
tasks.withType(Test) {
jacoco.includeNoLocationClasses = true
}
ext {
getFileFilter = { ->
def jacocoSkipClasses = null
if (project.hasProperty('jacocoSkipClasses')) {
jacocoSkipClasses = project.property('jacocoSkipClasses')
}
//忽略类文件配置
def fileFilter = ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*', '**/*$ViewInjector*.*']
if (jacocoSkipClasses != null) {
fileFilter.addAll(jacocoSkipClasses)
}
return fileFilter
}
}
task jacocoTestReport(type: JacocoReport, dependsOn: ['testCoverageDebugUnitTest', 'createCoverageDebugCoverageReport']) {
group = "Reporting"
description = "Generate Jacoco coverage reports"
reports {
xml {
enabled = true
xml.destination file("build/reports/jacoco/jacoco.xml")
}
html {
enabled = true
html.destination file("build/reports/jacoco")
}
}
def fileFilter = project.getFileFilter()
//检测覆盖率的class所在目录(以项目class所在目录为准)
//gradle2.3 class所在目录
def coverageDebugTree = fileTree(dir: "$project.buildDir/intermediates/classes/coverageDebug", excludes: fileFilter)
//gradle3.2 class所在目录
def coverageDebugTreeNewGradle = fileTree(dir: "$project.buildDir/intermediates/javac/debug/compileDebugJavaWithJavac/classes", excludes: fileFilter)
def mainSrc = "$project.projectDir/src/main/java"
//设置需要检测覆盖率的目录
sourceDirectories = files([mainSrc])
//兼容gradle版本
classDirectories = files([coverageDebugTree, coverageDebugTreeNewGradle])
//以下路径也需要检查
executionData = fileTree(dir: project.buildDir, includes: [
'jacoco/testCoverageDebugUnitTest.exec', 'outputs/code-coverage/debugAndroidTest/connected/coverage.ec'
])
}
测试代码来源: Android 使用 jacoco 统计代码行覆盖率 无需安装运行
1. Cannot set the value of read-only property ‘classDirectories’ for task ‘:app:testNameOfMyFlavorDebugUnitTestCoverage’ of type org.gradle.testing.jacoco.tasks.JacocoReport.这是因为gradle版本不兼容的问题,将上述代码中文件获取由“=”改为.setFrom()。
示例 :sourceDirectories = files([mainSrc]) 改为 sourceDirectories.setfrom(files([mainSrc]))
参考文章: stackoverflow的相关回答
2. Cannot set the value of read-only property ‘sourceDirectories’ for task ':app这是依赖为引入的问题,具体是什么导致的不清楚,解决方案是在项目的build.gradle中添加allprojects
allprojects {
repositories {
google()
mavenCentral()
}
}
3. java.lang.NoClassDefFoundError: jdk/internal/reflect/GeneratedSerializationConstructorAccessor1
找不到类,解决方案就是将这个包去掉。
jacoco.excludes = ['jdk.internal.*']
可以看一下参考文章,上面写了三种处理方式。
参考文章:问题相关解决方案
参考文档gradle学习系列
gradle文档



