持续集成 记一次静态代码扫描实践

xinxi · 2020年06月14日 · 最后由 孤舟蓑笠翁 回复于 2022年06月25日 · 10912 次阅读
本帖已被设为精华帖!

背景

产品迭代速度越来越快,每个分支都有各自的业务范围和开发周期需求,QA 无法触及到代码本身的质量,导致暴露的问题越来越多.同时代码微服务架构模式具有服务间独立,可独立开发部署的特点,开发过程中无法对代码本身的质量情况得到反馈,集中测试时才去关注质量,这样一来当出现问题时,大大增加了问题诊断和原因定位的复杂度.

这个背景其实是大多数互联网公司的通用型问题,大家都是为了赶进度往往忽略了代码的质量,有的时候不是开发不想改,是时间成本不允许.往往到了项目后期,改代码的风险是非常的高.

现状

产品迭代节奏的提升,导致功能实现为主时,容易忽视掉代码底层模块间的互相影响,且开发代码改动信息沟通有遗漏时,会出现测试验证覆盖率的缺失,导致没有测试验证改动,直接发布上线的问题,造成不可预估的影响。目前质量验收集中在集成测试阶段,对开发过程质量没有监控,以至于发现问题集中在后期,使发版质量风险越来越大.

在我司技术团队上述这种问题还是发生过的,通常都是开发改了一些底层逻辑,没有评估好影响范围,导致上线后出现线上 bug.

应该怎么改善?

为什么做 (痛点)?

1、现在我们测试团队的测试结构是,业务 + 接口自动化脚本结合测试,但是发现的问题基本上黑盒的,无法从代码层面找出问题,或者说不能深入发现问题.

2、随着业务迭代越来越多,代码行数越来越多.可能会引入重复代码、代码复杂度高、不符合编程规范以及、安全漏洞等问题.

怎么做?

1、应该引入一套代码扫描机制,在测试阶段或者上线前扫描出严重问题并且必须修复严重问题.

2、构建一条自动化流水线,从提交代码 => 扫描代码 => 发送报告.

静态代码扫描初探

静态测试包括代码检查、静态结构分析、代码质量度量等。它可以由人工进行,充分发挥人的逻辑思维优势,也可以借助软件工具自动进行。代码检查代码检查包括代码走查、桌面检查、代码审查等,主要检查代码和设计的一致性,代码对标准的遵循、可读性,代码的逻辑表达的正确性,代码结构的合理性等方面;可以发现违背程序编写标准的问题,程序中不安全、不明确和模糊的部分,找出程序中不可移植部分、违背程序编程风格的问题,包括变量检查、命名和类型审查、程序逻辑审查、程序语法检查和程序结构检查等内容

上边提到的重点部分是 “可以发现违背程序编写标准的问题,程序中不安全、不明确和模糊的部分,找出程序中不可移植部分、违背程序编程风格的问题,包括变量检查、命名和类型审查、程序逻辑审查、程序语法检查和程序结构检查等内容”,

优点:

  • 1、不需要启动服务,就能扫描代码.
  • 2、通过规则自动化扫描代码,坐等报告.
  • 3、支持多语言
  • 4、人力成本低

缺点

  • 1、不能发现代码业务逻辑问题 (需要人工做 codereviews 机制)
  • 2、可能会扫描出很多问题,但是后期可以屏蔽一些基本比较低的规则.

工具选型

工具对比

  • FindBugs -一个开源的静态分析字节码的 Java (工具比较老,只能输出静态页面)
  • IntelliJ IDEA -跨平台的 Java IDE,具有自己的一套几百代码检查可在即时在整个项目的编辑和批量分析分析代码 (还是在 IDE 工具层面)
  • SonarQube -对代码质量的持续检查的开源平台。 https://www.sonarqube.org

工具很多应该怎么选?

需要一个能持续集成的、可视化展示数据、能扫描的能力强、扫描规则可定制化.

选择 SonarQube 工具

通过一番的技术调研后,我们选择了 SonarQube

  • 开源
  • 平台化
  • 扫描规则较多
  • 可持续集成,gitlab + jenkins + SonarQube 结合三个工具做持续集成.

SonarQube 的环境搭建

可以参考这个帖子

https://testerhome.com/topics/17117

如何落地?

上面讲了那么多都是纯理论,当然不能靠嘴皮子就能把活干了.

静态代码扫描不算是一种新的测试手段了,但是比如我们这种量级的小公司其实很多没有开展,所以需要一个给技术同学的推展过程和接受的过程.

面临的挑战

如何让大家了解和接受?

一个新的 “相当新的测试技术” 如果想搞的话,必须有一个技术调研,而不是拍脑子就去做了.

技术调研

我认为好的技术调研应该是如下几方面:

问题背景

这个简单来说就是解决了什么问题,或者基于什么问题背景.这个往往是最关键的,如果没有很强的背景去支撑很难落地.

解决思路

这块有点考察对事物分析的能力,比如解决问题应该去拆解问题、有一个流程图、并且这个思路经得起推敲.

解决成本

往往理想的丰满的现实是残酷的,解决问题都是有昂贵的人员和时间成本.

所有要做任务拆解,比如第一期花了多长时间、能做什么、解决了什么问题.

Demo 的可行性

一般在调研阶段,必须要去本地搭建一套调研产品,最起码了解清楚可行性有多大

如何落地

真正的落地就是要立项了,时间、人员、排期等

如何验证成果

过程可能对于大佬们往往不关心,成果或者成绩才是大家关心的.

可以定一些指标,例如第一期能发现 xx 个严重问题.

以下是我花了一周左右做的 “静态代码扫描可行性调研”

image

image

image

如何推展到业务中?

有了调研文档就可以约着相关人员开会讨论了,如果第一次推广最好别越所有人.最好找一些项目负责人或者项目小组.

在开会的时候让大家给出一些问题,综合大家意见看看是不是能落地、达成目标一致性.

如何能和迭代挂钩?

找一个比较容易的项目去做,比如项目结构简单、服务架构简单.刚开始做的时候,仅是为了验证这个事 “靠不靠谱”.

当时我们找了一个后端相对比较新的服务、代码都是新写的.我们是在项目提测以后就开始去定期扫描.

使用了 jenkins + gitlab 这种比较简单的方式:

image

最好别直接给开发扔 SonarQube 的地址,把 bug 提到 bug 管理平台上.

image

原因有几点:

  • 需要手工做一些 bug 筛选
  • bug 的统计
  • bug 流程监管

image

如何能做结果验证?

相对来说就是能不能发现一些问题,千万别没有一个结论.

当时我们定的小目标就是,证明静态代码扫描是有可行性的、发现扫描项目不少于 5 个严重问题

另外一个就是项目结束的时候,有一个 bug 统计报告.

image

image

技术细节

下面聊一下技术方面的小细节和使用工具的方法.

范围

理想状态下能够覆盖到目前产品技术团队研发的 S1、S2 级服务,扫描的编程语言包括:java(后端)/Android/iOS/Python。从成本考虑,优先选择一到两门编程语言走通流程(Java、OC),后续会推广到整个技术部

SonarQube 针对 java 的语言支持比较好,推荐先去弄后端服务.iOS 在调研的时候发现 SonarQube 的一些 OC 插件,扫描出来的结果偏差很大,所以放到了最后面去搞.

扫描规则

因为 SonarQube 对每一个语言有很多中规则,在每个规则中又有很多种类型.

当时发现如果使用了默认的 java 规则,一个项目项目最起码能扫描出几百的问题,如果把这些问题都提 bug 开发会炸了.

image

image

需要精简规则,仅打开 Bugs 等级的规则,每次扫描出来的 “有效” 问题少多了.

image

大致总结了一下发现 bug 的高频问题:

  • 数据库未关闭
  • 空指针应该被捕获
  • 资源应该被关闭
  • 变量命名不规范
  • 变量应该用 final 声明
  • 代码重复度

扫描分支

可能一个项目会被扫描多个分支,需要在 SonarQube 区分代码分支.

以 maven 项目为例子:

mvn sonar:sonar -Dsonar.branch=xxxx

SonarQube 对应的项目名字后缀的分支名字

image

报告展示

自带的报告

SonarQube 每次会把最新的数据存在数据库,但是最新的数据会覆盖老数据,不能查看历史数据.

image

自定义报告

因为不能查看历史数据,所以需要每次扫描完成后,把扫描结果存一份到测试管理平台上,需要有如下几步:

  • SonarQube 中添加 webhook

image

  • 保存报告后端接口

这里会用到 SonarQube 的一些 api 接口

image

  • 前端展示报告

image

测试通知

因为我们公司用的是企业微信沟通,所以每次静态代码扫描完成后都会把结果发到企业微信群中.

image

扫描策略

扫描的策略大概有几种,目前我们是定时构建触发.

  • 监控活跃或者 master 分支,当提交代码的时候出发自动化代码扫.
  • 部署服务后出发自动化代码扫描.
  • 每天晚上定时自动化代码扫描.
  • 上线打包构建自动化代码扫描.

如何修改扫描问题

首先要和开发确认定义清楚哪些问题是必须改的.
例如 Bugs 中的阻断和严重的必须上线前修改

小结

静态代码扫描是相当长的测试周期、并且覆盖项目的范围比较广.

如果一个公司像尝试去做这方面,最好有一个架构涉及或者清晰的调研结果.

和自动化构建工具结合的时候,尽量使用开源的、或者公司内部的自动部署平台.

在人员投入上,最好能有一个专职的人去做,并且有一定的代码基础.

参考

1、阿里巴巴 java 编程规范
https://alitech-private.oss-cn-beijing.aliyuncs.com/1528269849853/Java_manual.pdf?Expires=1584004146&OSSAccessKeyId=LTAIqKGWQyF6Vd3W&Signature=xZ0QYCJoTpGutc7xMYmYIK4S/HE%3D

2、让所有代码都经过检查
https://cloud.tencent.com/developer/article/1371896

共收到 16 条回复 时间 点赞
19楼 已删除

阿里规范扫描也能包括一部分吧,所以是不是 SonarQube 规则越多才能体现他的价值

赞一个,之前也想也写一下我的实践过程,觉得这篇基本把我要写的都写了。
静态扫描不是简单的引入一个工具、部署一下就完事儿的,这也是这个文章的优点,写了一个完整的技术 topic 实践过程。

补充几点:

  1. 多分支支持是 sonarqube 的收费版本的特性之一,但是社区也有开源插件支持,比用多项目区分效果好一些。
  2. 规则集的选择不仅要考虑问题等级,还要考虑业务特性,比如有些业务比较在意安全性,可以把安全相关的规则都加上。
  3. 除了 Jenkins,还可以尝试一下 gitlab ci,这种方式接入成本更低,体验更好。有插件可以直接把问题展示在 commit 页面,对研发的体验更好。
rihkddd 回复

嗯 好的 最近我也在 gitlab ci 这款 具体的还没尝试过

陈恒捷 将本帖设为了精华贴 06月15日 20:52

结合公司内部实际的一个很好的落地时间经验,加个精鼓励下

我这边也用 jenkins+sonar 开源版在公司使用着。还集成了 dependency-check 的依赖包安全扫描,然后整个任务调度是 jenkinsfile, 又做了 jenkinsfile 模板化方便根据项目生成 jenkinsfile,为了每周能输出总体报告,还进行 web 模拟登陆和接口调用再放倒 plt 绘图生成邮件发送。
命名是个很苦恼的事情,楼主说的直接提到 BUG 管理工具的想法很好,但我们公司现状不太允许,项目大多质量不太行和人力不足,慢慢这个东西也就是项目上线的时候会重视下😆 。 share happines

更多情况下还是依赖于开发自定义插件扫描


如果有兴趣了解原理的可以看看 B 站这个课程。
做的难度>>>>使用难度。

Dobby 回复

可以加个联系方式,交流下吗,最近也在做这一块。有点无从下手

楼主有没有碰到 sonar webhook 的状态 偶尔是 Server Unreachable

仅楼主可见

我也在做这个,给 sonar 配置 postgresql 数据库的时候有点费劲,靠着各种百度把问题都解决了也跑起来,个人感觉最重要的不是一扫描完就扔给开发说让他们去改,开发很忙,不一定有时间改,这个扫描需要有人推动,不是工具搭建起来扫一下就行了,扫描发现的问题、以及问题跟进解决等等是最重要的,所以需要根据业务需要规划扫描规则,扫描出来问题的处理方法,比如约定哪些需要改,什么时候改,哪些可以先不改,这个东西是一个长期的工作,最最重要是要有人推动持续使用起来,否则就是白搭。

很好的实践分享,值得借鉴

膜拜前辈,前段时间也练手了一下,但是未能在公司落地,也就没有进一步的学习了。没能力去推,可能也没有大佬那么有说服力的调研文档啥的吧,继续努力了。

xinxi 回复

图挂掉啦,可以帮忙修复下吗?

膜拜大佬,17 年大佬就已经落地了 sonar,太牛了

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册