写点什么

代码质量管理的探索实践(下)

  • 2020-10-28
  • 本文字数:4854 字

    阅读完需:约 16 分钟

代码质量管理的探索实践(下)

代码质量管理的探索实践(上)介绍了版本管理和质量检查的相关工具,本文将为大家介绍单元测试覆盖率、质量报告等代码质量管理的过程。

5、 检查单元测试覆盖率的相关技术

单元测试案例写好了,如何得到执行覆盖率报告?早期,我们使用的是 maven-cobertura 插件,它通过对代码编译后的字节码做“打桩”处理,为每行代码都挂上一个计数器,maven- surefire 插件执行单元测试代码时,这些计数器就留下了测试代码的“脚印”,测试结束后将这些计数器进行统计分析得到的报表就是单元测试覆盖率报告了。



图 9 被 cobertura 打桩后的 Java 代码(反编译)



图 10 某个工程的单元测试覆盖率概览



图 11 某段代码的覆盖率提示


上图绿色部分代表已经测试覆盖的代码,前面的数字分别代表行号和测过的次数,if 分支前面也有执行过的次数,但因分支条件没有完全覆盖只能标记为未覆盖的红色。类似的单元测试覆盖率检查工具也很多,比如 Emma(JaCoCo 的前身)、JMockit-cover 等工具都提供了 Maven 插件,可以根据具体质量检查环境的要求配合使用,同时 Emma 提供了 Eclipse 插件支持,开发人员可以方便的在运行 JUnit 后在代码窗口看到覆盖率结果。



图 12 Emma 覆盖率工具在 Eclipse 中的效果


依托覆盖率报告插件,我们就可以对单元测试完成情况进行统计了,这些工具可以生成出直观的代码单元测试工作报告。


通常开发人员会使用 Emma 来做本地覆盖率检查工具,因为它支持 Eclipse 插件方式运行,那么服务器上如果用 Cobertura 来跑单测覆盖率就有可能和开发人员本地跑的不太一致,甚至有时 Cobertura 的 HTML 和 XML 报告两种形式的结果还能不一样。现今,我们更推荐在质检服务器上也使用 JaCoCo 这个工具来进行单元测试覆盖率检查。


JaCoCo 与 Cobertura 相比的优势:


  1. 支持 JVM 代理模式,可以动态打桩(On-the-fly),不依赖 classpath;

  2. 支持多次运行;

  3. 支持 Java1.8;

  4. 可以和 Emma 得到同样的结果(这点对开发人员很重要)。



图 13 JaCoCo 报告


6、 缺陷快递?如何让开发人员最快的看到最新的报告

鉴于我们在开发云上工作,信息只能在云上流转,但是需要接收报告的人都在云下,及时通知到该解决问题的人则需要耗费很多人力资源才能完成。且不说要安排人员定时收集数据发布质量报告到 espace 群里,还要要求开发人员关注质量报告,安排定期通知提醒,搞不好还得上考核手段,想要缩短问题解决时间需要投入很多的资源。


那么消息能否传递的更快、更直接?我们可以想到的是,开发人员日常都是通过 Eclipse 之类的 IDE 进行开发,如果能将质量报告推送到开发界面上不就好了,既能节省人力和报告存储资源,也能缩短反馈路径,保证最短的时间内将问题反馈到大家面前,应该是个一举多得的事情。



图 14 通过 P8 Tools 插件将 Jenkins 报告映射到 Eclipse 对应的项目上


首先将 Jenkins 输出的报告生成为 Json 格式,然后在 Eclipse 上使用开发辅助插件(我们手里刚好有个 P8 开发工具插件)后台刷新这个报告,一旦持续集成有新的报告产生,通过工程或者包视图的展示就能完成对开发人员的消息送达了。


结合 Eclipse 本身的项目展现方式,开发人员手里在开发哪个产品,插件就可以把哪个产品的报告状态展示出来,就好像将后台报告直接推送到了这个产品对应的开发人员面前。我们还做了信息格式的定制功能,开发人员也可以在信息栏根据自己想要看到的报告信息进行定制展示。


理论上,我们可以将 Jenkins 质量扫描出的问题和开发人员手中负责的代码进行技术比对并实时展示哪些代码行是有问题的,这比让开发人员去报告中找自己负责的代码更精准,更便捷。这样便通过了技术方式给每位开发人员配备了一个专属的“报告查看人”,时刻紧盯自己在开发的项目报告扫描情况,一旦出现问题可以随时链接到 Jenkins 上查看问题。



图 15 质量报告通过 P8 开发工具反馈在 Eclipse 状态栏的效果


7、 从质量报告到开发指挥棒

单元测试报告、安全扫描报告、日报、周报、投产报告,有了各种工具以及这些工具带来的质量数据,如何将这些技术工具转化为管理工具,在这里分享两点经验。


第一个经验 :问题发现的及时性比全面性和权威性更重要


  • 首先,通过对 Jenkins 的配置我们逐步整理各种质量检查的环境依赖关系,任务里增加脚本分析代码变更的原因。比如,当单元测试代码提交时,不影响有效代码,只需触发单元测试,就只进行覆盖率检查;当功能代码(main)提交时,则要进行全面检查,确认是否产生了新缺陷,这样就避免了大量不必要的重复检查,节约了系统资源。



图 16 我所常用的产品质量检查任务流程图


  • 其次,定时 PollSCM 获取版本状态,发现变更立即提取版本和变更情况,进行编译检查,触发相应的产品检查任务。

  • 第三,在独立的任务中进行各项子任务,不在一个大流水线里做很多的事情,降低质量任务依赖,避免等待。

  • 第四,群集管理,在多数服务器上配置环境依赖较低的相同工具,比如编译检查,让 Jenkins 分配资源,在专用服务器上配置环境依赖较高的工具,配置守候任务,比如 Fortify 检查。

  • 第五,收集各种质量检查结果,形成产品质量原始数据报告,方便单独查看。

  • 第六,通过任务间依赖关系,主动触发下游质量检查工作进行。

  • 第七,设置定期执行任务,确保代码的持续健康性,这点对于非常规需求产品尤为重要,能及时发现外围变更(例如,框架升级,环境配置变化)引起的问题,建议最长间隔周期为“周”,也就是每周所有产品都必须过捡一次。



图 17 Jenkins 中某个质量任务的总揽视图及报表


第二个经验 :开发人员能够理解的指令比枯燥的问题数量更为重要


医院体检报告上的数据大多数人都是看不懂的,但是医生可以,医生通过专业的分析,通俗易懂的解释,病人才能够理解病情。质量数据不加工不整合,不做人性化的展示也就是一堆枯燥的数据而已,管理团队投入大量资源提供了纷繁复杂的报告,开发团队还要花费更多的时间和人力去应对这些报告,是种双输的结果。


如何让质量数据发挥最大的潜能?我们的做法是让 Jenkins 和各种工具进行标准化数据输出,尽量将不同形式的报告输出成标准的样式,降低开发人员学习成本。然后使用外部工具进行数据收集,加以数据透视图、数据字典等信息辅助,再通过不同的数据展示设计得到质量管理需要的报告。


数据是枯燥的,也是能说话的,要看你去怎么展现。比如,我们希望在某个时间段快速提升单元测试覆盖率,那么我就使用单元测试提升度趋势,周、月、季度提升数量,来反映计划与执行之间的差异。增加各开发组之间的数据对比关系,突出工作效果差异,促成竞争效应。我们会在各种报告中用颜色、箭头等标识指出工作目标,定期发送到开发群里或开发界面上,希望引起开发人员的注意,再加上一些鼓励和惩罚机制,让这些数据作为开发工作的指挥棒,指导大家开展质量提升工作。



图 18 单元测试覆盖率汇总



图 19 组合后的质量报告



图 20 单元测试计划完成情况报告


作为质量管理者,还有一些工作是不能忽视的:比如说,质量趋势分析,在一段考核周期内,质量是否向更好方向发展,发展的速度如何?哪些代码易出现问题,哪些问题是共性问题各组都有出现,具体点说就是共性分析和差异分析,再比如说开发人员的工作效率。这些可能就需要做代码质量管理的人员通过一定的数据累积和基于经验的数据分析了,要面对面和大家解释清楚,代码管理者这时候承担的就是健身教练的角色,要告诉大家开发习惯哪里不好,优先做哪些调整效果会更好。


现在也有些质量工具平台能做到一部分趋势分析,比如 SonarQube。



图 21 某产品的 SonarQube 报告

代码质量管理平台 SonarQube

SonarQube 是一个开源平台,用于管理源代码的质量。SonarQube 不只是一个质量数据报告工具,更是代码质量管理平台。支持的语言包括:Java、PHP、C#、C、Cobol、PL/SQL、Flex 等。主要特点:


  • 代码覆盖:通过单元测试,将会显示哪行代码被执行

  • 改善编码规则

  • 搜寻编码规则:按照名字,插件,激活级别和类别进行查询

  • 项目搜寻:按照项目的名字进行查询

  • 对比数据:比较同一张表中的任何测量的趋势


SonarQube 将作为自动化单元测试反馈报告统一展现平台,包括:单元测试覆盖率、成功率、代码注释、代码复杂度等度量数据的展现。



图 22 SonarQube 任务列表展示


SonarQube 不完全能自己支持全部的质量检查,因为它的插件还比较少,可以通过 Jenkins 进行调度,然后将测试结果推送到 SonarQube 数据库中,形成互补关系。


SonarQube 提供了一套基于互联网开发经验的问题严重程度和修复成本的评估,可以为软件项目进行问题修复成本的评估和软件整体质量的评分,辅助项目管理者进行质量管理。


8、 代码质量细化到人,问题才能回到源头

代码的质量管理,换个角度看是将人这个开发过程中最大的不确定因素进行量化管理。


单元测试覆盖率体现的是代码行的有效测试情况,各种静态扫描体现了哪些代码行写的有问题,编译报错返回的是错误出现在哪一行代码上,质检工具拿到的是代码,反馈的问题位置也是代码行。因为没有把代码和人挂上钩,就没办法把问题直接反应到开发人员身上,也就造成了前面说的一些管理困境。


代码上有个特定的标签是 @author,JTest 工具便可以读取这个标签来进行代码到人的转换。但 @author 也是开发人员写上去的,很难确保代码作者信息的准确性。


ClearCase 和 Git 都为我们提供了提交记录,可以让我们得到每一行代码的作者。


我们开发了几个工具读取版本管理工具里面的作者提交信息,替代 @author 标签给出代码行和开发者的对应关系,以标准格式输出,方便各种工具复用。



图 23 Git 获取代码作者的关键代码



图 24 CC 获取代码作者的关键代码


通常,我们的开发都是以版本为计划单位的,但是质量扫描是以全量代码为扫描范围的,不能要求所有的工具都支持增量报告,我们如何从全量的质量报告里筛选出当前版本的数据?特别是单元测试覆盖率检查里,我们如何判断当前版本的代码是不是都已经完成了单元测试案例的编写?该提醒谁,该提升哪些代码行的覆盖率?这就先要得到版本变更的准确信息。好在 ClearCase 基线比对和 Git 的 git diff 都能输出版本差异数据,再加上作者信息加工,我们就拿到了版本变更和作者情况的完整信息了(下图,黄色是变更位置信息,diff 格式)。



图 25 基线比较加作者信息整合的结果



图 26 版本问题报告和整体质量报告的关系图


有了版本维度的变更数据信息,再用这个信息和全量的质量报告做一个交集匹配,大部分的质量工具就可以做出增量报告,即版本新增问题分析,并且将问题对应到具体的开发者身上了。以单元测试为例,我们不仅能给出当前版本产品的变更情况和有效代码覆盖情况,还有代码未覆盖的明细数据。



图 27 单元测试覆盖率产品和开发者统计效果


我们手里已经有了工程级、项目级、文件级、代码行级的质量报告,现在又将这些数据归属到人,得到作者级的质量报告。它可以为每一名开发者提供准确的质量工作指引,项目管理者也得到了一份开发者维度的产出情况和问题情况报告。开发者不再需要在各种报告中翻看是不是有自己所辖的代码问题,只需要看有没有自己的名字。我们还可以通过邮件或即时通讯工具将问题直接推送给相关人员,节约了问题分配的成本。


再进一步设想,我们已经能够打通作者、版本和缺陷的链接,如果能在这个链上再增加项目的需求项或测试案例等其他信息,是不是就有可能将全生命周期信息全部关联起来,从而为精细化的项目管理提供可靠的数据支持。可能也就不再需要各种数据报送和情况收集了。


9、 最后

整套质量管理体系的重点在于确保质量管理的有效实施,可以提前发现风险问题、释放实施压力,改变以往没有科学有效的工具和监管方法,仅靠开发人员经验和态度的管理模式。我们的诉求是不需要开发人员过多的关注质量工具的技术细节,只要参与其中按照报告要求指引去工作便能享受它所带来的效果。通过跟随团队代码质量管理的过程,变被动质量管控为主动质量意识提升。


希望本文能够抛砖引玉,将我在这几年来的思路和成果展示给大家,供战友们参考和指正。也希望有更多的开发人员和管理人员能和我们走到一起,让我们的代码质量管理工作越做越好。


本文转载自公众号金科优源汇(ID:jkyyh2020)。


原文链接


代码质量管理的探索实践(下)


2020-10-28 14:062428

评论

发布
暂无评论
发现更多内容

远程沟通高效的自我总结| 社区征文

卢卡多多

初夏征文

淘宝大数据分析案例(百万数据集Hadoop项目)

王小王-123

大数据分析 淘宝大数据 淘宝业务数据 淘宝项目可视化

leetcode 416. Partition Equal Subset Sum 分割等和子集(中等)

okokabcd

LeetCode 动态规划 数据结构与算法

在Hadoop环境里面统计西游记文章的词组(hdfs实验)

王小王-123

mapreduce hadoop统计词频 hadoop项目 文本统计分析

[译]在软件开发行业工作 6 年后,那些年我曾改过的观念

宇宙之一粟

感悟 6月月更

整整面试两月,凭借这份15w字Java面试刷题宝典成功入职阿里

Java全栈架构师

Java spring 程序员 面试 算法

什么是IGMP?IGMP与ICMP有啥区别?

wljslmz

网络协议 6月月更 IGMP 组播

微博系统中”微博评论“的高性能高可用计算架构

Geek_e8bfe4

“微博评论”的高性能高可用计算架构

Pengfei

@Scheduled注解的坑,我替你踩了

慕枫技术笔记

后端 6月月更

web3 的身份验证之以太坊签名消息

devpoint

区块链 以太坊 Web3.0 6月月更

淘宝数据可视化大屏案例(Hadoop实验)

王小王-123

海量数据 大数据分析 淘宝项目 hadoop实验 hive项目

传统微服务框架如何无缝过渡到服务网格 ASM

阿里巴巴云原生

阿里云 微服务 云原生 Service Mesh 服务网格 服务网格

HashMap分析-新增

zarmnosaj

6月月更

基于学生选课数据库分析(Hadoop实验)

王小王-123

hadoop 大数据分析 学生选课项目 数据库项目

架构实战营模块 5 作业

Roy

架构实战营

声网自研传输层协议 AUT 的落地实践丨Dev for Dev 专栏

声网

Dev for Dev 网络传输

穿越过后,她说多元宇宙真的存在

白洞计划

Serverless 在阿里云函数计算中的实践

阿里巴巴云原生

阿里云 Serverless 云原生 函数计算

我们如何拿到自己满意的薪资呢?这些套路还是需要掌握的

看山

闲聊

架构实战营模块5作业

挖了蘑菇哩斯

架构实战营

Seata 与三大平台携手编程之夏,百万奖金等你来拿

阿里巴巴云原生

阿里云 开源 云原生 seata

透过华为军团看科技之变(五):智慧园区

脑极体

架构实战营模块 5 作业

Naoki

架构实战营

M1笔记本居家办公的痛点及解决方案 | 社区征文

IT蜗壳-Tango

6月月更 初夏征文

Jetpack之Room的使用,结合Flow

yechaoa

android flow JetPack 6月月更 Room

基于Hadoop豆瓣电影数据分析(代码+原理)

王小王-123

大数据 数据分析 基于Hadoop豆瓣电影

架构实战营毕业总结

哈喽

「架构实战营」

MySQL,MVCC详解,快照读在RC、RR下的区别

乌龟哥哥

6月月更

初识Hadoop之概念认知篇

王小王-123

hadoop hadoop概念

小心transmittable-thread-local的这个坑

看山

Java’

代码质量管理的探索实践(下)_软件工程_林超_InfoQ精选文章