当前位置: 首页 > 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.hskmm.com/?act=detail&tid=15016

相关文章:

  • LVS 服务器 知识
  • 07-django+DRF项目中统一json返回格式 - 详解
  • 软工第二次作业——个人项目
  • 近十年 CSP-J 复赛知识点分布表
  • AT_arc181_d [ARC181D] Prefix Bubble Sort
  • 【MySQL】使用C/C++链接mysql数据库 - 指南
  • 枚举子集
  • cv-css 快捷方式,将指定节点的计算样式获取下拉 获取tailwind网页样式成原生样式
  • day002
  • PyTorch图神经网络(四)
  • 软件工程:构建数字世界的基石
  • Avalonia 学习笔记07. Control Themes(控件主题)
  • matter 协议的架构;
  • matter 协议解析;
  • 9月23日
  • Nordic 的支持对Matter 协议的支持;
  • nRF54LM20A USB
  • nRF54LM20A GRTC
  • 2025年10款最佳生产力提效chrome插件推荐,亲测有用
  • Avalonia 学习笔记06. Page Layout(页面布局)
  • 发表第一篇文章,谈谈对软件工程的理解
  • nRF54LM20A 芯片分析;
  • 第二天
  • 内部类
  • NRF54L15 两者结合的jlink保护机制(硬件+软件)
  • 软件测试员的核心技能:一文掌握等价类划分与边界值分析
  • 《CBI 技术有聊》对话 OpenCSG:智能体落地困境与企业转型的必然路径
  • 个人对软件工程的理解
  • 9/23
  • NUMERICAL RESULT (2025/09/23)