当前位置: 首页 > news >正文

第6.2节 Android Agent制作<三>

第6.2节 Android Agent制作<三>

6.2.2 覆盖率文件解析jacoco-parser

由于移动端的特殊性,jacoco插件无法直接在java项目中直接引用,然后解析覆盖率文件。于是就开发了一下android端的工具 ,打包成jar包来解析覆盖率文件。

1,项目整体情况

早期这个工具只有EC文件解析功能,后来做覆盖率合并的时候,我又添加上了覆盖率数据的去除和添加功能,形成jacoco-parser2.0.jar,针对这个工具的功能,会有另外的文章介绍,此处只介绍覆盖率EC文件的解析。

2,覆盖率文件解析类

通过在项目中添加jacoco插件,然后引用插件的类处理EC文件,根据探针解析出对应的覆盖率数据在文件中的行,再反查对应的函数,输出为json文件。
i
import com.google.gson.Gson
import org.jacoco.core.analysis.Analyzer
import org.jacoco.core.analysis.CoverageBuilder
import org.jacoco.core.analysis.ICounter
import org.jacoco.core.tools.ExecFileLoader
import java.io.File
/*******************************************************************************
*  Read jacoco exec file, java class file, and source file to produce coverage lines.
* @author songxianfeng@kuaishou.com
*/
data class CoverageInfo(
val filename: String,
var covered: Set,
var nocovered: Set
)
class JacocoParserOperation {
val Covered = setOf(ICounter.FULLY_COVERED, ICounter.PARTLY_COVERED)
val NoCovered = setOf(ICounter.NOT_COVERED)
fun readJacocoECFileContent(ecFileNames:Array,classesDir:File,sourceDir: Array,output: File){
val ecFileLoader = ExecFileLoader()
for (file in ecFileNames) {
ecFileLoader.load(file)
}
val coverageBuild = CoverageBuilder()
val analyzer = Analyzer(ecFileLoader.executionDataStore, coverageBuild)
analyzer.analyzeAll(classesDir)
val sourceFileGroup = sourceDir.map {
it.walk().filter { file -> file.isFile }.toSet()
}.fold(setOf()) { s, e -> s + e}.groupBy { it.name }
val bundle = coverageBuild.getBundle("")
val coverageMap = mutableMapOf()
bundle.packages.map { pkg ->
//println("${pkg.name} - ${pkg.sourceFiles} - ${pkg.lineCounter}")
for (c in pkg.classes) {
val sourceFile =
sourceFileGroup[c.sourceFileName]?.findLast { f -> f.path.indexOf(c.packageName) > 0 } ?: continue
var coverageInfo = coverageMap[sourceFile.toString()]
if (coverageInfo == null) {
coverageInfo = CoverageInfo(sourceFile.toString(), setOf(), setOf())
}
//                println("class: ${c.name}, source: ${c.sourceFileName}")
for (i in c.firstLine..c.lastLine) {
if (c.getLine(i).status in Covered) {
coverageInfo.covered += i
} else if (c.getLine(i).status in NoCovered) {
coverageInfo.nocovered += i
}
}
coverageMap[sourceFile.toString()] = coverageInfo
}
}
//        coverageMap.forEach { (k, v) -> println("$k -> $v") }
val gson = Gson()
val content = gson.toJson(coverageMap)
output.writeText(content)
}
}

3,工具使用方法

(1)先对项目进行打包
在项目根目录下执行以下命令:
./grwdlew jar

(2)调用工具解析文件
java -jar ./build/libs/jacoco-parser-2.0-SNAPSHOT.jar
-e /Users/***/first_merged.ec
-c /Users/****/build_classes_8900
-s /Users/****/packages
-o /*****/ecparse.json
  • -e 指定EC文件路径
  • -c 项目源码文件对应的类文件
  • -s 项目的源码文件路径
  • -o 解析后的输出结果,格式为{"文件路径":[函数列表],"文件路径1":[函数列表1]}
http://www.gsyq.cn/news/10505.html

相关文章:

  • LVS 服务器 知识
  • 【有源码】基于LTM模型+大素材的电信客户流失数据分析系统-基于机器学习的电信客户流失预测与分析框架-基于客户画像的电信流失用户识别与分析平台
  • Apifox-windows-latest.exe 安装教程(附详细步骤,一键下载安装指南)​
  • PyTorch图神经网络(四)
  • 告别材料乱堆、用电违规!AI 施工监测系统覆盖重点施工场景隐患
  • Computer Architecture
  • Nordic 的支持对Matter 协议的支持;
  • Avalonia 学习笔记06. Page Layout(页面布局)
  • NRF54L15 两者结合的jlink保护机制(硬件+软件)
  • 个人对软件工程的理解
  • 用C/C++重构PowerShell:全面绕过安全机制的技术解析
  • Which side of a 2d curve is a point on
  • HTTPS 映射如何做?(HTTPS 映射配置、SNI 映射、TLS 终止、内网映射与 iOS 真机验证实战) - 指南
  • 大三上第一篇日志
  • 0923模拟赛总结
  • Hive采用Tez引擎出现OOM的处理办法
  • VMware之后下一个消失的永久许可,Citrix Netscaler VPX旧版许可已经失效了!你升级了吗?
  • Feminism in China
  • 大模型微调示例四之Llama-Factory-DPO - 教程
  • n8n+MySQL实现数据库查询!
  • firewalld 端口流量转发
  • Day20封装的初步认识
  • 【Qt开发】显示类控件(三)-> QProgressBar - 详解
  • 完整教程:数据结构与算法-树和二叉树-二叉树的存储结构(Binary Tree)
  • 工业相机与镜头靶面尺寸的关系:从原理到选型的避坑指南 - 教程
  • 提供优雅报错能力
  • Security Onion Solution
  • 详细介绍:MySQL进阶学习
  • 时序数据库 TimechoDB V2.0.6 发布 | 新增查询写回、黑白名单等功能
  • 第二篇