3.3.2 使用Sonar进行代码检查

笔者曾经听到开发人员这样谈论代码质量:“它能用啊!”“客户没有抱怨啊!”抑或“有自动化测试啊!”但事实真的如此吗?答案显然是否定的。

代码的质量不应该也不能只依赖于单元测试、回归测试等自动化测试,代码检查也非常重要,它甚至可以帮助我们尽早发现代码的问题,从而提升产品的质量。广义上的代码检查分为机器检查和人工评审。常见的做法是将二者结合。针对前者,我们团队选择了代码检查工具Sonar,并收获了不错的效果。本节我们就来介绍如何使用Sonar进行代码检查。

Sonar作为一款开源的代码质量管理工具,可以帮助我们持续检查代码质量。它支持20多种主流开发语言,开发人员既可以使用内置的规则进行检查,也可以很轻松地对规则进行扩展。

1.代码质量报告

Sonar能提供实时的代码质量报告,内容涵盖可靠性、安全性、可维护性、测试覆盖率、重复代码等指标,以及用来衡量代码质量的质量配置(Quality Profile)和质量关口(Quality Gate)。

● 可靠性:Sonar可以检查出潜在的代码缺陷(Bug),这些缺陷如果不及时修复,会影响软件产品的正常运行。

● 安全性:Sonar内置了一系列的安全性规则,诸如代码注入、SQL注入、Cookie未设置HttpOnly标签等,这些规则多由权威机构提出。安全性问题一经发现应当立即修复。

● 可维护性:Sonar针对各类语言总结了常见的代码异味(code smell)。代码异味往往会暴露出深层次的问题,如果不加以纠正,这些问题可能会在未来导致严重的后果。

● 测试覆盖率:Sonar可以收集单元测试的代码覆盖率报告。

● 重复代码:重复代码几乎是最常见的代码异味。消除重复代码应当是开发人员重构代码的主要目标之一。

● 质量配置:质量配置是一组规则的集合,我们可以使用Sonar默认的规则集合,也可以自定义规则集合。应当根据实际情况设定质量配置,使整个团队遵循同一套标准。

● 质量关口:质量关口定义了代码质量的评判标准。以Sonar默认的质量关口为例,只有测试覆盖率大于80%,重复代码小于3%,可靠性、安全性、可维护性的评级不低于A时,代码质量才被认为是合格的(passed),否则会被标记为不合格(failed)。

图3-7展示了一个名为“Android”的应用的代码质量报告。左侧是对代码指标的统计,右侧是应用正在使用的质量配置和质量关口。

2.持续代码检查

开发人员可以在本地IDE中使用静态代码检查插件SonarLint进行本地分析。此外,Sonar也提供了一套持续的代码检查流程,从而将持续集成和代码质量报告有机地结合起来。

开发人员在使用Git新建PR时,会触发Jenkins流水线。我们可以在流水线中增加分析步骤,并使用Sonar分析器(Sonar Scanner)进行代码分析,集成方式如下。

图3-7

Sonar分析器会将质量报告发送到Sonar服务器,分析参数示例如下。

其中,sonar.sources指源代码路径,sonar.host.url代表服务器的地址,sonar.projectKey是源代码所在应用在Sonar服务器的唯一标识,每个应用应该有自己的projectKey。

Sonar服务器会将当前的分析结果和代码主干分支的最新分析结果进行对比,生成基于PR的报告。我们既可以在流水线的构建中查看代码质量是否合格,也可以在Sonar网页端查看详细的质量报告。图3-8是PR质量报告示例,由于最新代码中有两处代码异味,不符合质量关口中的零代码异味的要求,因而代码质量被标记为不合格(Failed)。

此外,Sonar也支持和Git集成,并在PR中展示检查结果。使用时,需要创建GitHub App并使其指向Sonar服务器,然后在Sonar服务器的全局配置中配置好GitHub的地址和App的ID,最后调整分析器的参数。PR的分析示例如下。

其中,sonar.pullrequest.key是指PR的ID,sonar.pullrequest.branch是指PR的源分支,sonar.pullrequest.base代表PR指向的分支。

Sonar服务器生成代码质量报告后,会将结果回写到PR中。图3-9是上述结果在PR中的展示情况。代码合并应当在代码被标记为合格后发生。

图3-8

图3-9

每个团队都有一套自己的代码规范指南,或自己的代码质量标准。通过使用Sonar进行持续检查,我们可以将指南与标准流程化,从而规范成员的代码开发习惯,提高代码质量。