网站首页 > 文章精选 正文
目录
- JaCoCo简介
- 技术能做什么
- 实现原理
- 最佳实践及注意事项
- 进阶用法
- 集成 JaCoCo agent 到 CI/CD 环境
- 如何优化测试覆盖率不达标
- 通过SonarQube集成JaCoCo来展示每次构建的覆盖率情况
JaCoCo简介
定义
JaCoCo(Java Code Coverage)是一个为Java应用程序提供代码覆盖率衡量的开源工具。它可以检测Java字节码的执行情况,生成全面的代码覆盖报告。
历史背景
在JaCoCo出现之前,Java程序员已经有了一些代码覆盖率工具可供选择,如Cobertura、Emma等。但这些工具要么功能有限,要么配置复杂、效率低下。JaCoCo诞生于2009年,旨在提供一个可靠、高效且易于集成的代码覆盖率解决方案。
创新点
- 高效:JaCoCo直接在运行时插桩字节码,无需进行额外的构建步骤,大大提高了效率
- 易于集成:JaCoCo可以轻松集成到Maven、Ant等构建工具中,与CI/CD无缝衔接
- 全面覆盖:支持多种代码覆盖类型,如指令、分支、循环、行、方法等
- 丰富报告:生成HTML/XML/CSV格式报告,支持多种报告视角和过滤选项
- 跨平台:工作于JVM之上,支持所有基于Java的应用程序
发展趋势
代码覆盖率分析日益成为高质量软件交付的标配,JaCoCo作为主流工具将持续获得支持和增强。未来或将完善对最新Java版本和框架的支持,提升可视化报告质量,简化工作流程集成等。
技术能做什么
- 无侵入性插桩利用Java Agent机制,在目标JVM启动时注入JaCoCo的运行时代理代理分析类文件,找到需要插桩的位置,并修改字节码指令修改后的类将记录运行时的执行路径,用于覆盖率统计
- 支持多种覆盖类型通过ASM字节码分析和修改框架,精确分析Java字节码结构识别方法、分支、循环等代码结构,进行精准插桩运行时跟踪这些代码结构的执行情况,统计覆盖率数据
- 生成报告汇总运行时收集的原始执行数据根据报告格式需求,将原始数据与源代码进行映射处理使用模板生成HTML/XML/CSV格式报告,包括统计数据和源码高亮视图
- 轻量高效只在被测程序的运行时进行一次字节码改写,不影响编译过程插桩代码只添加少量指令,与原程序指令平行执行,开销很小无需频繁读写文件,执行性能接近不插桩场景
- 报告可视化使用JavaScript和CSS渲染HTML报告,生成代码高亮视图报告分为文件/包/类等多个层级,支持交互式展开折叠条形图将不同覆盖类型直观展示,辅助分析质量状况
- CI集成为Maven、Ant、Gradle等主流构建工具提供插件扩展将覆盖率报告作为质量关卡,阻止低覆盖率应用部署上线与CI服务器JenkinsBamboo等无缝集成,实现持续交付
实现原理
工作流程
- JaCoCo Agent加载通过Java命令行参数-javaagent启动JaCoCo代理或者在运行时,通过Instrumentation接口动态加载代理代码JaCoCo代理初始化,准备修改应用字节码
- 字节码扫描JaCoCo利用ASM框架,扫描应用所有的类文件和字节码识别需要插桩的目标代码,如分支、循环、方法调用等
- 插桩改写在目标代码处插入计数器,用于统计执行路径覆盖情况识别已插桩过的类,避免重复插桩浪费资源
- 执行跟踪代理启动执行数据服务器,用于接收每个计数器的数据应用执行时,相应计数器将执行路径数据发送给服务器
- 数据采集执行数据服务器实时汇总收集计数器执行数据应用退出前,JaCoCo代理保存最终的执行数据文件
- 报告生成读取执行数据文件,结合未插桩的类文件,生成汇总报告根据报告格式要求,渲染统计数据和源码视图
关键概念
- Java Agent:Java Agent是JVM启动时通过特殊选项指定的代码,可以对JVM进行监控、修改、增强等操作。JaCoCo以Java Agent形式注入代码,实现字节码插桩。
- ASM字节码工具:JaCoCo利用了ASM框架对Java字节码进行分析和修改。ASM提供了访问者模式API,可精确遍历、操作字节码指令序列。
- 执行数据服务器:JaCoCo的执行数据服务器充当数据收集器,用于接收插桩后的应用代码发送的覆盖率数据,汇总统计最终数据。
最佳实践及注意事项
最佳实践
- 排除无需测试的代码通过配置规则排除第三方类、实用类等无需测试覆盖的代码避免这些代码拉低整体覆盖率,影响质量评估准确性
- 针对产品覆盖率设置目标根据产品特点和质量要求,设置合理的覆盖目标新产品起步阶段,可设置70%以上的目标循序渐进提升成熟产品应设置90%以上较高目标,确保质量长期可控
- 集成到CI/CD流程将JaCoCo覆盖率检查集成到持续集成和交付流程中构建验证通过后自动生成报告,低于阈值时阻止部署上线持续监控和反馈覆盖率,指导测试用例优化和补充
- 代码审计和评审定期审计JaCoCo反馈的未覆盖代码评估这些未覆盖代码的重要性及潜在风险针对高危区域补充测试用例,提高覆盖率
- 与测试框架集成JaCoCo可与主流单元测试框架如JUnit、TestNG等集成在运行测试用例时自动启动JaCoCo跟踪覆盖率简化了测试、质量管理的工作流,高效获取覆盖率反馈
注意事项
- 插桩开销JaCoCo插桩后的应用会有一定程度的性能损耗实际生产环境不应保留插桩代码运行,仅开发测试时启用
- 报告一致性生成报告的源码版本要与被测试的班次保持一致避免类删除、移动等导致源码映射错位
- 多线程场景JaCoCo需要同步多线程并发执行数据开销会随线程数增加而线性增长
- 易遗漏的覆盖场景枚举类、内部类等容易被测试用例遗漏多线程、异常等场景也需注意测试覆盖
- 自动生成代码对于框架或反射自动生成的代码,JaCoCo无法进行插桩应通过其他手段如mock或集成测试补充这部分覆盖率
进阶用法
集成 JaCoCo agent 到 CI/CD 环境
- 当 CI/CD 管道运行时,它首先会执行编译构建和单元测试的任务。这个阶段,我们通常会通过配置 Maven 或 Gradle 插件来启动 JaCoCo agent。例如,如果使用 Maven,我们可以在 pom.xml 中添加 JaCoCo 插件的配置。
- 在配置JaCoCo agent时,你需要为其指定一个输出目录,该目录用于存放生成的覆盖率报告。当单元测试运行时,JaCoCo agent 会对字节码进行增强,跟踪执行路径,然后收集覆盖率数据。
- 当单元测试运行结束后,JaCoCo agent 会生成覆盖率报告(比如 XML 或 HTML 格式),并将其保存到你之前指定的输出目录。
- 然后,可以使用一些 CI/CD 插件(比如 Jenkins 的 JaCoCo plugin)来解析这些覆盖率报告,展示覆盖率信息。
- 在测试任务完成,JVM 关闭时,JaCoCo agent 也会被自动卸载。因为 JaCoCo agent 是以 JVM 参数的形式加载的,其生命周期与 JVM实例一致。
也就是当 CI/CD 流程的构建任务开始时,它会启动一个新的 JVM 进程,并在这个进程中运行构建脚本(例如 Maven 或 Gradle 脚本),加载 JaCoCo agent,并执行单元测试。这所有的过程都是在这一个 JVM 进程中完成的。当构建任务结束后,这个 JVM 进程就会关闭,同时也会卸载 JaCoCo agent。但是这并不会影响你的应用的正常运行,因为你的应用运行在另一个独立的 JVM 进程中
如何优化测试覆盖率不达标
- 增加测试用例:检查是否有未覆盖的代码段或路径,为这些部分编写对应的测试用例。
- 进行边界值和异常情况测试:确保测试中包含判断逻辑的边界情况,例如为空、为0、为极限值等情况。同时需要测试异常处理路径,例如处理无效输入的逻辑。
- 优化代码结构:如果代码中存在过于复杂的逻辑判断和多重嵌套,可以考虑重构代码,以简化控制流程。
- 使用白盒测试:白盒测试指的是直接测试代码的内部逻辑,这能帮助我们找到哪些路径未被覆盖。
- 导入正确的依赖:确保所有的测试库和代码库都正确导入,未被误引导至错误的库中。
- 使用Mock对象:某些情况下,为了测试一段代码,可能需要编写复杂的上下文环境。在这种情况下,可以使用Mock对象来创建这些上下文。
最后,覆盖率是一个参考指标,不能完全代表代码质量。重要的是要做到对产品功能和业务逻辑的全面覆盖。
通过SonarQube集成JaCoCo来展示每次构建的覆盖率情况
- 直接使用JaCoCo不支持增量测试覆盖率报告,它将报告所有测试的覆盖率,而不只是针对某次commit的增量修改部分代码。
- 如果需要得到增量覆盖率报告,就需要整合其他的工具。例如,“SonarQube”就支持增量覆盖率管理,能够结合CI/CD工具,在每次代码修改后触发增量覆盖率分析。也就是说,结合SonarQube,可以看到针对某次commit修改部分的覆盖率数据。
- 注意,SonarQube默认情况下会分析全量的代码。为了得到每次commit的修改的增量覆盖率报告,你需要在设置中启用增量模式(Leak Period模式),设置为previous_version,这样它将只分析自上次版本发布以来的新代码。
猜你喜欢
- 2025-01-16 博茨瓦纳首颗卫星BotSat-1成功完成组装、集成和测试
- 2025-01-16 web 自动化测试,一定得掌握的 8 个核心知识点
- 2025-01-16 软件集成测试计划
- 2025-01-16 Spring Boot微服务测试:集成与契约测试
- 2025-01-16 使用Playwright搭建自动化测试工程
- 2025-01-16 Spring Boot集成测试:确保应用质量
- 2025-01-16 集成电路制造工艺-测试工程
- 2025-01-16 专业的嵌入式软件测试工具TESSY,针对C/C++代码单元/集成测试
- 2025-01-16 软件集成测试策略和方法
- 2025-01-16 18单元与集成测试
- 最近发表
- 标签列表
-
- newcoder (56)
- 字符串的长度是指 (45)
- drawcontours()参数说明 (60)
- unsignedshortint (59)
- postman并发请求 (47)
- python列表删除 (50)
- 左程云什么水平 (56)
- 计算机网络的拓扑结构是指() (45)
- 稳压管的稳压区是工作在什么区 (45)
- 编程题 (64)
- postgresql默认端口 (66)
- 数据库的概念模型独立于 (48)
- 产生系统死锁的原因可能是由于 (51)
- 数据库中只存放视图的 (62)
- 在vi中退出不保存的命令是 (53)
- 哪个命令可以将普通用户转换成超级用户 (49)
- noscript标签的作用 (48)
- 联合利华网申 (49)
- swagger和postman (46)
- 结构化程序设计主要强调 (53)
- 172.1 (57)
- apipostwebsocket (47)
- 唯品会后台 (61)
- 简历助手 (56)
- offshow (61)