1. build.gradle
在项目的 build.gradle
中引入 jacoco core
依赖:
apply plugin: 'maven'
buildscript {
repositories {
jcenter()
google()
maven { url "https://oss.sonatype.org/content/repositories/snapshots" }
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.3'
classpath "org.jacoco:org.jacoco.core:0.8.5"
}
}
allprojects {
repositories {
google()
jcenter()
}
}
2. 新建 jacoco-report.gradle
在项目根目录新建一个 jacoco-report.gradle
文件,其中主要定义了一个 Gradle 任务:jacocoCoverageTestReport
。如下:
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*.*', '**/*Test*.*', 'android/**/*.*']
if (jacocoSkipClasses != null) {
fileFilter.addAll(jacocoSkipClasses)
}
return fileFilter
}
}
/**
* buildTypes {
* debug {
* minifyEnabled false
* }
* coverageDebug {
* minifyEnabled false
* testCoverageEnabled true
* }
* }
*/
task jacocoCoverageTestReport(type: JacocoReport, dependsOn: ['testCoverageDebugUnitTest', 'createCoverageDebugCoverageReport']) {
reports {
xml.enabled = true
html.enabled = true
}
def fileFilter = project.getFileFilter()
def coverageDebugTree = fileTree(dir: "$project.buildDir/intermediates/classes/coverageDebug", excludes: fileFilter)
def coverageDebugTreeNewGradle = fileTree(dir: "$project.buildDir/intermediates/javac/coverageDebug/classes", excludes: fileFilter)
def mainSrc = "$project.projectDir/src/main/java"
sourceDirectories = files([mainSrc])
classDirectories = files([coverageDebugTree, coverageDebugTreeNewGradle])
executionData = fileTree(dir: project.buildDir, includes: [
'jacoco/testCoverageDebugUnitTest.exec', 'outputs/code-coverage/connected/*coverage.ec'
])
}
3. app/build.gradle
在 SDK/App module 对应的 build.gradle
中进行 jacoco 任务配置:
- 引入
jacoco-report.gradle
; - 添加
coverageDebug
BuildType。
如下:
apply plugin: 'com.android.library'
apply from: '../jacoco-report.gradle'
android {
compileSdkVersion 28
buildToolsVersion "29.0.1"
defaultConfig {
minSdkVersion 15
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
debug {
minifyEnabled false
}
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../proguard-rules.pro'
}
coverageDebug {
minifyEnabled false
testCoverageEnabled true
}
}
testOptions {
unitTests.all {
jvmArgs '-noverify'
}
unitTests {
includeAndroidResources = true
}
unitTests.returnDefaultValues = true
}
lintOptions {
abortOnError false
}
}
dependencies {
// ...
// other dependencies
// for test.
testImplementation 'junit:junit:4.12'
// power mockito
testImplementation 'org.mockito:mockito-core:2.8.9'
testImplementation "org.powermock:powermock-api-mockito2:1.7.4"
testImplementation "org.powermock:powermock-module-junit4:1.7.4"
testImplementation "org.powermock:powermock-module-junit4-rule:1.7.4"
testImplementation "org.powermock:powermock-classloading-xstream:1.7.4"
}
3. 编写对应的测试用例
在对应 module 的 src/test/
目录下编写对应的代码测试用例。
4. 运行 jacocoCoverageTestReport
在 Android Studio 的 Gradle 任务窗格中,找到 project/module/Tasks/other/jacocoCoverageTestReport
这个任务,双击运行,即可生成代码行覆盖率报告。
5. 查看报告
打开 project/module/build/reports/jacoco/jacocoCoverageTestReport/html/index.html
文件,即可查看各个代码文件的行覆盖率。
覆盖率报告 HTML 打开后一般如下: