jacoco入门_Android jacoco 代码覆盖率测试入门

前言

最近同事搞了一个基于 jacoco 统计 Android 代码覆盖率测试的功能,可以统计每天手工测试的代码覆盖率.抱着好奇的心态,自己也学习一下 jacoco,陆陆续续搞了三天终于有点结果了.

本文介绍仅仅在源码中加入少量代码就可以完成代码覆盖率覆测试.

代码配置

build.gradle

在 app 目录下的 build.gradle 配置 jacoco

apply plugin: 'jacoco'

jacoco {

toolVersion = "0.7.9"

}

dependencies {

compile fileTree(include: ['*.jar'], dir: 'libs')

androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {

exclude group: 'com.android.support', module: 'support-annotations'

})

compile 'com.android.support:appcompat-v7:25.1.1'

compile 'org.jacoco:org.jacoco.core:0.7.9'

compile 'com.android.support.constraint:constraint-layout:+'

}

def coverageSourceDirs = [

'../app/src/main/java'

]

task jacocoTestReport(type: JacocoReport) {

group = "Reporting"

description = "Generate Jacoco coverage reports after running tests."

reports {

xml.enabled = true

html.enabled = true

}

classDirectories = fileTree(

dir: './build/intermediates/classes/debug',

excludes: ['**/R*.class',

'**/*$InjectAdapter.class',

'**/*$ModuleAdapter.class',

'**/*$ViewInjector*.class'

])

sourceDirectories = files(coverageSourceDirs)

executionData = files("$buildDir/outputs/code-coverage/connected/coverage.ec")

doFirst {

new File("$buildDir/intermediates/classes/").eachFileRecurse { file ->

if (file.name.contains('$$')) {

file.renameTo(file.path.replace('$$', '$'))

}

}

}

}

写入 ec 文件

自定义一个 JacocoUtils 类,可以根据反射拿到方法、类的执行代码,写入到.ec 文件

public static void generateEcFile(boolean isNew) {

// String DEFAULT_COVERAGE_FILE_PATH = NLog.getContext().getFilesDir().getPath().toString() + "/coverage.ec";

Log.d(TAG, "生成覆盖率文件: " + DEFAULT_COVERAGE_FILE_PATH);

OutputStream out = null;

File mCoverageFilePath = new File(DEFAULT_COVERAGE_FILE_PATH);

try {

if (isNew && mCoverageFilePath.exists()) {

Log.d(TAG, "JacocoUtils_generateEcFile: 清除旧的ec文件");

mCoverageFilePath.delete();

}

if (!mCoverageFilePath.exists()) {

mCoverageFilePath.createNewFile();

}

out = new FileOutputStream(mCoverageFilePath.getPath(), true);

Object agent = Class.forName("org.jacoco.agent.rt.RT")

.getMethod("getAgent")

.invoke(null);

out.write((byte[]) agent.getClass().getMethod("getExecutionData", boolean.class)

.invoke(agent, false));

Log.d(TAG,"写入" + DEFAULT_COVERAGE_FILE_PATH + "完成!" );

} catch (Exception e) {

Log.e(TAG, "generateEcFile: " + e.getMessage());

Log.e(TAG,e.toString());

} finally {

if (out == null)

return;

try {

out.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

使用 Application 生成 ec

继承 Application 类,重写 onTrimMemory 方法,系统会根据不同的内存状态来回调

系统提供的回调有:

Application.onTrimMemory()

Activity.onTrimMemory()

Fragement.OnTrimMemory()

Service.onTrimMemory()

ContentProvider.OnTrimMemory()

OnTrimMemory的参数是一个int数值,代表不同的内存状态:

TRIM_MEMORY_COMPLETE:内存不足,并且该进程在后台进程列表最后一个,马上就要被清理

TRIM_MEMORY_MODERATE:内存不足,并且该进程在后台进程列表的中部。

TRIM_MEMORY_BACKGROUND:内存不足,并且该进程是后台进程。

TRIM_MEMORY_UI_HIDDEN:内存不足,并且该进程的UI已经不可见了。

可以根据 level == TRIM_MEMORY_UI_HIDDEN 来确定 app 已经至于后台,此时调用 generateEcFile 方法.

//判断是否是后台

@Override

public void onTrimMemory(int level) {

super.onTrimMemory(level);

if (level == TRIM_MEMORY_UI_HIDDEN) {

isBackground = true;

notifyBackground();

}

}

private void notifyBackground() {

// This is where you can notify listeners, handle session tracking, etc

Log.d(TAG, "切到后台");

JacocoUtils.generateEcFile(true);

}

操作步骤

给予 app 读写 sdcard 权限

因为我的是简单的 demo 代码,启动没有弹窗询问读写 sdcard 权限,

Android6.0 以后是动态获取权限了,所以需要手动去设置中把 sdcard 权限打开,实际项目应该不存在手动打开的步骤.

手工执行

安装 app->操作 app->app 至于后台->分析 ec 文件.

自动化执行

可以结合 monkey 和 UI 自动化,我简单写了个 shell 脚本.从编译 app、启动 app、app 至于后台、自动展示 jacoco 报告

#!/usr/bin/env bash

#当前在环境为Project/app目录

apk_path=`pwd`/app/build/outputs/apk/app-debug.apk

report_path=`pwd`/reporter/index.html

echo "打包app"

gradle assembleDebug

adb uninstall com.weex.jasso

echo "安装app"

adb install ${apk_path}

echo "启动app"

adb shell am start -W -n com.weex.jasso/.Test1Activity -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -f 0x10200000

sleep2

echo "关闭app"

adb shell am force-stop com.weex.jasso

rm -rf `pwd`/new.ec

rm -rf `pwd`/report

adb pull /sdcard/jacoco/coverage.ec `pwd`/new.ec

macaca coverage -r java -f `pwd`/new.ec -c `pwd`/app/build/intermediates/classes/debug -s `pwd`/app/src/main/java --html `pwd`/reporter

echo "jacoco报告地址:"${report_path}

open -a "/Applications/Safari.app" ${report_path}

效果

266fc5dce9707c5fac442bfced08cd4b.png

adf822c92c1847f619bc45f56624ea82.png

macaca coverage 生产报告

使用 gradle 的 jacocoTestReport 也可以生产报告,也是大多人使用的方式,本文就不做介绍了,主要介绍使用 macaca coverage 方法.

macaca coverage 可以生成 jacoco 报告,不仅可以生成 Android 项目,也可以生产 iOS、web 项目.具体使用请查看https://macacajs.github.io/zh/coverage.

安装macaca-coverage命令:

npm i macaca-cli -g

macaca coverage -h

npm i macaca-coverage --save-dev macaca coverage命令:

macaca coverage -r java -f `pwd`/new.ec -c `pwd`/app/build/intermediates/classes/debug -s `pwd`/app/src/main/java --html `pwd`/reporter

项目代码 https://github.com/xinxi1990/jacocodemo.git

在项目根目录有个jacaco_test.sh,可以完成自动化测试.

学习帖

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值