现在android 开发都喜欢用模块化的方式,然后以aar文件的方式导入到主项目,但是这对于统计代码覆盖率就有点麻烦了,因为统计时候都忽略这些第三方库,那么我们如何将这些aar文件纳入到代码覆盖率的统计中来呢?请看本篇文章。参考资料

何为模块化开发

问题

像这些aar文件加入到主项目后,我们在使用jacoco的时候,都无法统计这些aar文件的覆盖率,比如说主项目是一个空项目,其他所有的代码都分散在其他模块中,也就是以后的以aar文件加入过来,如果你这个时候在主项目中统计代码覆盖率,永远都是0%。其实原因很容易理解,比如你在java开发中的一些第三方jar包肯定不在jacoco的统计范围内。

解决方法

见参考文章,这位大牛利用了一种变通的方式,为每一个aar项目打开了代码覆盖率的统计开关,然后再利用一个任务删除了每一个aar项目中重复的jacocoagent.jar包。具体的操作方式如下:

假设A项目为主项目,B项目为aar项目。操作如下:

A项目配置

首先我们要在A项目的build.gradle打开代码覆盖率的开关

在android/buildTypes/debug下加入testCoverageEnabled = true

在dependencies下加入如下配置:

debugCompile project(path:':B', configuration: 'debug')

path后面跟什么,需要你自己调整,目的是为了指引到B项目,因为我们在setting.properties文件中配置了这个项目,所以在这里可以通过冒号+项目的方式直接引用。

上面的配置说的是,在编译debug版本的包时,引用B项目的debug版本。那既然这样说 ,肯定需要在B项目配置点啥了,来切换到B项目下的build.gradle下

B项目配置

开启代码覆盖率开关,也就是testCoverageEnabled = true

然后一点就是修改默认的publish选项,默认的情况下只发布release版本,我们现在更改成发布debug和release两个版本。在android{}下加入publishNonDefault true 。这样我们就能找到debug版本的aar文件,切这个debug版本加入了代码覆盖率。

删除多余的jacocoagent.jar包

因为多处打开了代码覆盖率的开关,会有多个jacocoagent.jar包,编译的时候会报错,这个时候需要删除多余的jacocoagent.jar包,因为主项目中已经含有了,所以我们只需要删除了aar包下的即可。

task deleteJacocoagentJar {
doLast {
getTransitiveProjectDependencies(this, 'debugCompile').each { project ->
delete "build/intermediates/exploded-aar/${rootProject.name}/${project.name}/unspecified/debug/libs/jacocoagent.jar"
}
}
}
def getTransitiveProjectDependencies(project, configuration) {
def projectDependencies = project.configurations."$configuration".getAllDependencies().withType(ProjectDependency)
def dependencyProjects = projectDependencies*.dependencyProject
dependencyProjects.each {
dependencyProjects += getTransitiveProjectDependencies(it, configuration)
}
return dependencyProjects.unique()
}
android {
applicationVariants.all { variant ->
variant.dex.dependsOn deleteJacocoagentJar
deleteJacocoagentJar.mustRunAfter variant.javaCompile
}
}

这个时候我们使用增强版方式来获得代码覆盖率,安装debug版本到手机,操作一段时间后,获取coverage.ec文件,下面是我两次操作获得的coverage.ec文件

shell@android:/mnt/sdcard/coverage $ls -l
-rw-rw-r-- root sdcard_rw 227 2015-05-12 06:52 coverage.ec_1431413536233
-rw-rw-r-- root sdcard_rw 484 2015-05-12 07:06 coverage.ec_1431414353987
-rw-rw-r-- root sdcard_rw 3777 2015-05-12 07:07 coverage.ec_1431414416960
shell@android:/mnt/sdcard/coverage $

第一个文件,是没有上述配置,产生的代码覆盖率的数据,我pull到本地,生成的报告的代码覆盖率是0%,无论你操作多少,都是0%。

第二个文件,是上述配置完成后,我打开应用关闭后,产生的代码覆盖率的数据。

第三个文件,是上述配置完成后,我打开应用,进行不同的操作,产生的代码覆盖率。

后续问题

代码覆盖率的数据得到了,那么生成报告的问题就摆在面前了,因为这个时候要包含aar项目的源码了,大家尝试下如何生成报告。(参考文章中也有)