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,可以完成自动化测试.

学习帖

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/563303.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uinty粒子系统子物体变大_Unity的粒子系统(一)基础篇

简介闲来无事,仔细的学习一下粒子系统,也当是给自己做个笔记方便之后进行回顾。引擎版本:Unity2018.3创建一个ParticleSystem创建方式:1、Hierarchy-->Effects-->ParticleSystem第一种创建方式创建结果2、gameObject-->A…

java定义返回码常量_码出规范(四)常量定义

01各位屏幕前的读者朋友大家早上中午晚上凌晨好,本文是《码出规范》专题的第四篇,文中参考阿里巴巴最新发布的《Java开发手册》,结合《springboot2.x独门秘籍》专题中的项目开发进度,学以致用,让你在开发中码出高效&am…

centos下载mysql_python数据分析之路——centos下载并配置mysql与navicat的使用

python数据分析之路——centos下载并配置mysql与navicat的使用在之前的文章中已经说明了如何购买并配置一台自己的服务器,那么在安装完anaconda之后,为了之后方便用Django进行网站开发与数据分析,需要对数据库进行配置,那么在数据…

mysql 解压缩安装_[mysql] MySQL解压缩安装步骤

以前装的MySQL出问题了,只好卸载了。又下载了一个mysql-5.6.24-win32.1432006610.zip。msi文件直接安装就行了。这里需要解压到指定目录,配置后可使用。环境变量配置:在 mysql根目录下修改 my-default.ini :# These are commonly set, remove…

mysql数据库如何创建表_mysql数据库如何创建数据表

mysql数据库创建数据表的方法是:可以通过CREATE TABLE语句来创建,基本语法:【CREATE TABLE ([表定义选项])[表选项][分区选项];】。要注意的是,创建数据表不能使用SQL语言中的关键字。在 MySQL 中,可以使用 CREATE TAB…

mysql 主从一致性_mysql 主从一致性保证

MySQL 主备的基本原理MySQL 主备切换流程.png主备同步流程图备库 B 跟主库 A 之间维持了一个长连接。主库 A 内部有一个线程,专门用于服务备库 B 的这个长连接。一个事务日志同步的完整过程是这样的:在备库 B 上通过 change master 命令,设置…

php study是什么,phpstudy与wamp区别的区别是什么?

phpstudyphpstudy是一个php运行环境的集成包,用户不需要去配置运行环境,就可以使用,phpstudy不仅是一款比较好用的php调试环境工具,并且还包括了开发工具和常用手册,对于新手是有很大帮助的。phpstudy集成最新的Apache…

java全局机制,java实现全局异常机制

先上自己的代码,后整理下原理知识。下面是自己实现的全局异常机制1.继承Exception,自定义异常类​package com.zichen.xhkq.exception;/**** Title: CustomException* Description: 系统自定义的异常类型,实际开发中可能要定义多种异常类型* authorCNZZ*…

mysql crash定位分析_MySQL实例crash的案例详细分析

【问题描述】我们生产环境有一组集群的多台MySQL服务器(MySQL 5.6.21),不定期的会crash,但error log中只记录了重启信息,未记录crash时的堆栈:mysqld_safe Number of processes running now: 0mysqld_safe mysqld restarted接下来…

matlab 读取照片imread,利用matlab读取图像

怎样用matlab读取20张图片并依次展示出来指定路径下 单个文件夹data中所有图像 P .\data\;% 图像文件夹路径 img_path_list dir(strcat(P,*.jpg));%获取该文件夹中所有jpg格式的图像 N length(img_path_list);%获取图像总数量 for j 1:N%逐一读取图像 image_name img_path…

python元素定位input button_python+selenium 定位到元素,无法点击的解决方法

报错selenium.common.exceptions.WebDriverException: Message: Element is not clickable at point (234.75, 22). Other element would receive the click: 需要点击的按钮页面显示不了,需要下拉滚动条,能看到按钮了才能点1、尝试下拉一段滚动条&#…

python模拟浏览器请求的库_基于Python模拟浏览器发送http请求

1.使用 urllib2 实现#! /usr/bin/env python# -*- codingutf-8 -*-import urllib2url"https://www.baidu.com"req_header {"User-Agent":"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11&…

owncloud8 php,owncloud-8.2.3

安装依赖Red Hat Enterprise Linux and CentOS 6 still ship with PHP 5.3. ownCloud requires PHP 5.4 or better. There areseveral third-party repositories that supply PHP 5.4, but you must use the Software Collections (SCL) repository to bein compliance with yo…

php7 提示500错误解决,升级php7出现500错误怎么办

升级php7出现500错误怎么办发布时间:2020-08-24 10:40:45来源:亿速云阅读:69作者:小新小编给大家分享一下升级php7出现500错误怎么办,希望大家阅读完这篇文章后大所收获,下面让我们一起去探讨吧&#xff01…

oracle 怎么 制造崩溃,oracle数据库崩溃

通过幸存oracle文件修复oracle9i数据问:我没有备分oralce,也没有导出数据库,现在操作系统崩溃了,但是oracle目录下的文件很完整,请问如何修复我的表?答:建一个相同的数据库(磁盘目录相同,否则要改init文件&…

php 500 yii,yii2.0出现500错误怎么办

1、首先开启web/index.php defined(YII_DEBUG) or define(YII_DEBUG, true); 将此改为true;看下报错的问题:Exception (Invalid Configuration) yii\base\InvalidConfigException with message The directory is notwritable by the Web process: /home/…

受迫阻尼 matlab 仿真,MATLAB系统仿真报告——有阻尼受迫振动系统

一、 问题描述有阻尼受迫振动的结构及基本原理图一 有阻尼的受迫振动系统图1为有阻尼的受迫振动系统,质量为M,摩擦系数为B, 弹簧倔强系数为K。拉力、摩擦力和弹簧力三都影响质量为M的物体的加速度。如果系统的能量守恒,且振动一旦…

php 数组 定义 遍历,php针对数组的定义、遍历及删除

本篇文章主要介绍php针对数组的定义、遍历及删除,感兴趣的朋友参考下,希望对大家有所帮助。本文实例讲述了php实现搜索一维数组元素并删除二维数组对应元素的方法,具体如下:定义一个一维数组一个二维数组如下$fruitarray(apple,or…

Linux怎么对文件内容trim,Linux平台下SSD的TRIM指令的最佳使用方式(不区别对待NVMe)...

SSD写数据会出现什么问题SSD读写的单位不是位,而是一个块。如果要改变这个块中的一位,首先要将整个块擦写成1,然后再写入更新的数据。为了解决擦写块的低效,SSD的策略是将需要改写的块,读取出来,进行数据修…

linux命令行如何上翻,Linux学习教程-获取可用命令行参数 or 文件上下翻转和左右翻转...

导读前面使用的,有几个用到了参数如ls -l, head -n 6等,需要注意的是跟参数之间要有空格。获取可用命令行参数终端运行man ls可以查看ls所有可用的参数,上下箭头翻页,按q退出查看。(man: manual, 手册)ctehbio:~/data$ man lsNAME…