这里我们不说原理,只说集成过程且只统计单元测试的代码覆盖率
1.创建jacoco.gradle文件
首先在项目根目录创建script文件夹,然后jacoco.gradle如下:
apply plugin: 'jacoco'
tasks.withType(Test) {
jacoco {
includeNoLocationClasses = true
excludes = ['jdk.internal.*'] // Allows it to run on Java 11
}
}
android {
testCoverage {
jacocoVersion "0.8.10"
}
buildTypes {
debug {
testCoverageEnabled true
}
}
}
// 根据你productFlavor和buildType定义
def sourceName = 'devDebug'
def testTaskName = "test${sourceName.capitalize()}UnitTest"
// 如果需要统计androidTest的覆盖率,需要把createDevDebugCoverageReport这个task加到dependsOn里
// createDevDebugCoverageReport - this task for generate androidTest report, that need connect a devices
task jacocoTestReport(type: JacocoReport, dependsOn: ['testDevDebugUnitTest']) {
group = "JacocoReport"
description = "Generate Jacoco coverage reports on the ${sourceName.capitalize()} build."
reports {
xml.getRequired().set(true)
csv.getRequired().set(false)
html.getRequired().set(true)
// 这里重新定义jacoco生成的报告的位置
//to create coverage report in html
html.outputLocation.set(file("${buildDir}/reports/coverage"))
//for XML
xml.outputLocation.set(file("${buildDir}/reports/jacoco.xml"))
}
def fileFilter = [
// adapters generated by moshi
'**/*JsonAdapter.*',
//dao dir generated by room
'**/dao/**',
// Injector generated by hilt
'**/*GeneratedInjector.*',
'**/*EntryPoint.*',
// data binding
'**/databinding/**/*.class',
'**/databinding/*Binding.class',
'**/databinding/*',
'**/bumptech/*',
'**/BR.*',
// android
'**/R.class',
'**/R$*.class',
'**/BuildConfig.*',
'**/Manifest*.*',
'**/*Test*.*',
'android/**/*.*',
// 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 = []
def kotlinClasses = []
def javaSrc = []
rootProject.subprojects.each { proj ->
// ignore app project that contain many deprecated code
if (proj.name != 'app') {
javaClasses << fileTree(dir: "$proj.buildDir/intermediates/javac/$sourceName/classes", excludes: fileFilter)
kotlinClasses << fileTree(dir: "$proj.buildDir/tmp/kotlin-classes/$sourceName", excludes: fileFilter)
javaSrc << "$proj.projectDir/src/main/java"
}
}
sourceDirectories.from = files([javaSrc])
classDirectories.from = files([javaClasses, kotlinClasses])
// 这里注意定义executionData的文件夹位置
def executionDir = "${project.buildDir}/outputs/unit_test_code_coverage/${sourceName}UnitTest/${testTaskName}.exec"
executionData.from = files(executionDir)
print("executionData Dir:$executionDir")
}
由于最新版Android Studio生成.exec文件的位置不再是build/jacoco,所以这里要定义具体生成.exec文件的位置。
具体位置如下:
2.配置Jacoco
首先classpath
classpath('org.jacoco:org.jacoco.core:0.8.10')
然后在app下的gradle加入
apply("${project.rootDir}/script/jacoco.gradle")
在每一个非Application的gradle下加入
plugins {
id("com.android.library")
id("jacoco")
}
android {
buildTypes {
debug {
isTestCoverageEnabled = true
}
}
}
3.命令行得到代码覆盖率统计报告
待工程Sync完成以后就可以运行一下Command得到测试代码覆盖率的报告
./gradlew app:jacocoTestReport
最后查看App下的build文件夹
在coverage下的html里查看具体情况。