在之前的讲解里,我曾经提到过,静态测试的对象包括需求、设计和代码,也提到过代码审查的两种方式:一种是人工评审,另一种是基于工具的自动静态测试。在 CI 环境中我们可以通过 GitHub 的 Pull Request 特性来进行代码的人工评审。这一讲,我将带你学习自动的静态测试方法、工具和静态测试报告,以及自动化测试报告的生成。

代码分析(静态测试)

代码的静态测试,也叫静态分析,它不需要运行应用程序就可以对软件代码进行检查,并找出其中的缺陷。自动静态测试是指利用静态分析工具对代码进行自动扫描发现缺陷的技术,相对人工评审来说,它不需要投入太多人力就可以发现代码中的缺陷,是效率比较高的代码审查方式。

自动静态分析方法一般能够发现代码中的下列问题。

代码结构问题:重复性代码、高度耦合的代码等。

实现问题:资源泄漏、空指针引用、死循环、缓冲区溢出等。

可读性差、不规范的问题:有些代码没有缩进、变量在使用前未定义等。

这些功能对于查找一些代码的安全漏洞缺陷特别实用,比如有些程序如果接收到超出缓冲区的数据和参数,就会导致缓冲区溢出,攻击者利用精心构造的溢出数据就可以让程序执行其恶意代码,从而获得系统的控制权,达到入侵系统的目的。如果在研发阶段不能发现此类问题,上线后可能会造成重大的信息安全事故。比如 2003 年美国 Davis-Besse 核电站受到 Slammer 蠕虫攻击,就是因为程序中的缓冲区溢出漏洞被黑客利用而造成的。

要实现自动的静态测试,团队需要完成以下几方面的工作。

首先需要选择合适的静态分析工具。对于自动静态测试,仅仅借助工具进行测试还不够,并且无论采用哪种工具,团队都需要一起定义扫描规则,使用统一的规则进行静态测试。比如在开发过程中对发现的代码缺陷进行总结、提炼或抽象,把这些代码缺陷模式借助规则集、模型、解析树、形式化方法等方式描述出来,结合编程规范就形成了自定义的扫描规则。

其次,开发人员提交代码前应该先在本地开发环境里执行静态测试,结果可以做为人工评审(Code Review)的输入项进行分析,如果其中的典型或重大问题能让团队成员知晓并讨论如何避免,则可以有效地提高整个团队的代码能力和质量意识。

最后,将静态测试工具集成在 CI 环境中,静态测试将会成为持续集成活动的一部分,并且自动生成可视化的代码分析报告,发送邮件通知开发人员进行分析和修复工作。

优秀的静态分析工具

我们先从静态分析工具开始讲起,常用的工具有很多,这里只列出其中的一些,比如 Java 可以选择 PMD、FindBugs 等,C/C++ 语言可以选择 C++ Test、CppTest、Splint 等,Python 语言可以选择 Pylint、Pychecker、PyCharm 等。

FindBugs 通过检查 JAR 文件,将字节码与一组缺陷模式进行对比,从而发现可能的代码问题,它既提供可视化 UI 界面,同时也可以作为 Eclipse 或 IntelliJ DEA(简称 IDEA)插件使用。FindBugs 还为用户提供定制 Bug Pattern 的功能,用户可以根据需求自定义 FindBugs 的代码检查条件。

PMD 可以检查、分析 Java 源程序代码,并通过内置的编码规则对 Java 代码进行静态检查。同时,它也支持开发人员对代码检查规范进行自定义配置,主要检验潜在的 bug、未使用的代码、重复的代码、循环体创建新对象等问题。另外,PMD 还可以和多种 IDE 进行集成。

Checkstyle 是针对 Java 代码风格的检查工具,它偏重于代码编写格式的检查,包括 Javadoc 注释、命名约定、标题、Import 语句、修饰符等。

静态测试报告的自动生成

在实际使用中,代码分析工具一般通过各自的插件集成到 IDE(Elipse、IntelliJ DEA、Pycharm等)环境中,开发人员在提交代码前会对代码进行实时的静态测试。如图 1 所示,在 IDEA中安装了 3 个代码分析插件:SonarLint、Checkstyle 和 PMD。其中,PMD 和 Checkstyle 可以添加工具自带的代码规则,以及团队自定义的代码规则。

图 1 IDEA 中添加代码分析工具的插件

在 IDEA 中选择需要分析的源文件和分析工具,就可以得到如图 2 所示的代码分析结果。

图 2 代码分析结果

SonarLint 一般作为 IDE 的插件,用于开发人员进行本地的代码分析,以便在编程中及时发现问题、及时修改,以确保代码 push 到代码库前的代码质量,如图 3 所示。

图3 IDEA 中的 SonarLint 插件

SonarLint 可以和 SonarQube 集成,从而拥有更加丰富的代码规则集,而且在代码扫描分析完之后,其测试结果会上传到 SonarQube 服务器上,如图 4 所示,它以直观的可视化界面来展现代码质量及单元测试覆盖率。双击显示页面上的某个数字,就可以查看具体的信息等内容。

图 4 SonarQube 的测试报告

静态分析工具和 CI 调度工具的集成让静态测试成为持续集成的一部分,如果我们要让静态测试和 Jenkins 集成,就需要用到 SonarQube Scanners,实现代码自动扫描并上传报告到 SonarQube,这也是目前比较主流的应用方式。也就是说, SonarQube Scanners 依据 SonarQube 服务器中的代码规则库进行远程代码分析,而且可以和构建工具 Gradle、Maven、Azure DevOps 等集成。

图 5 就描述了这种 CI 环境中代码分析的工作流程。开发人员在本地开发代码并利用 SonarLint 进行实时代码分析,然后将代码 push 到代码仓库中,触发持续构建,之后采用 SonarQube Scanners 进行代码分析,持续集成结束后将代码分析结果发布到 SonarQube 服务器以呈现测试报告。SonarQube 服务器将代码规则集和分析结果存储在数据库中,缺陷则提交给开发人员。

图 5 SonarQube 在 CI 环境中的集成

下面是 Jenkins 流水线脚本示例,构建过程包括编译、部署、单元测试、代码覆盖率分析等,这些过程完成之后,Jenkins 会自动调用 sonarQube Scanners 执行代码静态测试,测试报告会自动上传到 sonaQube 的界面上。

自动化测试报告的自动生成

除了单元测试和代码静态测试,BVT、回归测试、性能测试等自动化测试也可以在 CI 环境中自动触发测试活动并生成测试报告。

下面的 Jenkins 流水线脚本给出了调用 Robot Framework 进行自动化测试的示例。当然,你需要在 Jenkins 里安装相应的 Robot Framework 插件。

Jenkins 可以生成 HTML 格式的报告,就像上面脚本里定义的。但是要得到更加美观的报告则需要集成第三方的测试报告生成工具。报告的生成有两种方式:

在 Jenkins 中集成测试报告生成工具然后自动生成报告;

在自动化测试框架中实现自定义的测试报告生成功能模块,然后通过 Jenkins 和测试框架的集成生成测试报告。

先说第 1 种方式,首先我们介绍两个测试报告生成的工具,即 Grafana 和 Allure2。

Grafana 是一款用 Go 语言编写的开源框架,它通过对采集数据的查询,以可视化的方式展现大规模的指标数据,是目前网络架构和应用分析中流行的时序数据(指带有时间戳的数据)展示工具。

Grafana 可以关联多种数据源,比如 MySQL、InfluxDB(开源分布式时序数据库)等。在 Jenkins 中安装 InfluxDB 插件后,将每次构建的信息存入数据库,就可以发送到 Grafana,按照时间顺序展示测试结果,包括由单元代码覆盖率统计工具和代码分析工具生成的结果。同时,利用 Grafana 可以建立测试结果和测试指标的实时监控面板,图 6 展示了 Jenkins 中多个流水线部署管道每次构建后的代码覆盖率。

图 6 Grafana 展示的代码覆盖率

顺便提一下,Grafana 的功能还不止如此,把它集成在部署流水线中,可以帮助我们实时呈现、监控 Kubernetes 容器集群的负载情况,包括集群 Pod、CPU、内存和外部存储等使用状态,如图 7 所示。

图7  Grafana 监控 Kubernetes 集群负载

另一款比较优秀的测试报告框架是 Allure2,它可以提供如图 8 所示的比较美观的测试结果概览,而且可以查看每个测试用例的测试结果、测试用例的描述等。

图 8 Allure 生成的测试报告 Overview

下面的 Jenkins 流水线脚本给出了自动化回归测试之后 Allure 自动生成的测试报告示例。脚本定义只有在测试失败时才会用邮件通知相关人员,但每次都会生成 Allure 测试报告,Allure 报告的链接会显示在 Jenkins 管理界面上。具体的配置方法你可以自己学习。

用户自定义的测试报告

只要把 Allure 这样的测试报告框架和 CI 环境进行集成,就可以自动生成比较美观的测试报告。如果团队需要自定义的测试报告以满足进一步的需求,Allure 还可以提供与自动化测试框架的集成,通过在测试脚本中添加 Allure 注解比如 @Story、@Issue、@Attachment,来实现测试报告的定制,这些功能包括关联用户故事、关联测试用例、定义测试用例级别、关联缺陷、为失败用例添加 UI 界面的截图等。

另外还有 ExtentReports,它也是一款可以和多个自动化测试框架集成,从而实现定制化测试报告的框架。图 9 展示了 ExtendReport 和测试框架集成后生成的自定义 HTML 报告,来自我公众号里的一篇文章,介绍了基于 Spock 的测试自动化框架,有兴趣的可以去看看。

图 9  ExtentReports 生成的自定义测试报告

这部分内容就介绍到这里了,下面我简单总结一下这一讲的内容:

代码的静态测试可以有效提高代码质量,合适的静态测试工具有 PMD、Splint、Pylint 或 SonarLint;

静态测试工具与 CI 环境集成后可以自动生成代码分析报告并让结果和缺陷信息可视化;

介绍了 3 种测试报告框架,即 Allure、ExtendReport 和 Grafana,前两个和自动化测试框架集成可以实现用户自定义的测试报告。

最后给你留两道思考题:你还知道有哪些用于生成测试报告的开源框架吗?平时希望生成怎样的测试报告?欢迎留言参与讨论。

-– ### 精选评论