谷歌研究人员进行了一项分析,这项分析揭示了该公司的工程师如何管理 10 亿行代码的代码测试覆盖率。
该图片来自于谷歌,其中彩色标识的行号(用红色矩形框突出显示)用来可视化地查看代码覆盖情况。行号如果被测试覆盖,则为绿色;如果没有被覆盖,则为橙色;如果没有检测该行,则为白色。
在软件开发中,一个称为代码覆盖率的常用度量标准,用于度量部署代码之前,所执行的测试覆盖到的系统代码的百分比。代码覆盖率通常由单独的软件程序自动测量,或者可以从命令行手动启动某些代码覆盖率工具。测试结果准确地显示了在运行测试套件时执行了哪些代码行,并且可以揭示哪些代码行可能需要进一步的测试。
理想情况下,软件开发团队的目标是 100% 的代码覆盖率。但在现实中,这种情况很少发生,因为有些代码块会走到很多不同的执行路径,也因为各种边缘情况,基于系统的需求,应该(或不应该)考虑这些边缘情况。
近年来,越来越多的谷歌项目已经很积极地引入了自动化代码覆盖率测试工具。
度量代码覆盖率已经成为软件开发和测试团队的常见实践,但是这种实践是否真的提高了代码质量,这个问题仍然存在争议。
一些人认为,开发人员可能把焦点放在了数量上,而非质量上,创建测试只是为了满足代码覆盖率,而不是足够健壮地识别高风险或关键的代码区域。其他人则对它的成本效益提出了担忧——它需要宝贵的开发人员时间来评审结果,而且不一定能提高测试质量。
对于像谷歌这样的大型组织(拥有 10 亿行代码,每天接收数万次提交并支持七种编程语言)来说,度量代码覆盖率尤其困难。
谷歌的 AI 研究人员 Marko Ivanković and Goran Petrović最近的一项研究,提供了这家科技巨头代码覆盖率基础设施的幕后情况,它由四个核心层组成。底层组合了针对每种编程语言设计的代码覆盖率库,中间层将代码覆盖自动化流程集成到了公司的开发和构建工作流中。顶层使用代码编辑器和其他的定制工具,将代码覆盖信息可视化显示出来。
作为这项研究的一部分,Ivanković和 Petrović分析代码覆盖率在 5 年期间的采用率。他们发现,尽管谷歌没有强制规定代码覆盖率,但自 2014 年以来,采用率却一直在稳步增长。2018 年第一季度,超过 90% 的项目使用了自动的代码覆盖工具。
研究人员还从 3000 名随机选择的谷歌开发人员和其他非工程人员中,收集了 512 份关于代码覆盖率有用性的调查问卷。在受访者中,只有 45% 的人在代码修改时频繁使用代码覆盖率测试,而 40% 的人在进行代码评审时定期地使用代码覆盖率。
图表示例:来自谷歌谷歌的调查参与者在代码修改(红色)、检查代码更改(蓝色)和浏览代码更改(绿色)时,对代码覆盖率的有用性进行了评分。
Ivanković向 IEEE Spectrum 谈到了他们的这项研究,和代码覆盖在软件开发和测试中的作用。(为了清晰起见,以下采访记录经过了编辑和浓缩。)
IEEE Spectrum:为什么你认为代码覆盖率很重要?
Marko Ivanković:很多人可能期望我们说,“好的覆盖率减少 bugs 的数量。“这当然是其中的一个原因,但(我们发现的)更令人惊讶的是,即使覆盖率不能直接作为一种质量信号,它仍然值得计算。”
覆盖率可能对查看代码的人没有直接的帮助,但是对工具仍然有帮助——例如,分析依赖关系的工具。例如,如果代码 A 声明它依赖于代码 B,但是对代码 A 的测试永远无法触及代码 B,那么这种依赖可能不是真实的,自动化工具可以尝试删除它来简化代码库。
当然,实际实现要复杂得多。我们已经发现了许多这样的工具,它们可以使用我们的基础设施提供的覆盖率信息,来改进它们自己的功能。对于许多这些用例,代码覆盖率和代码质量之间的相关性根本不重要。
IEEE Spectrum:是什么激发了你研究谷歌的代码覆盖率?
Ivanković:因为我们面临着一个问题。在代码评审期间,我们花费了大量的时间试图弄清楚,测试是否真的测试到了这些评审的代码。那时,代码构建系统支持覆盖率计算,但是您必须手动激活它,并手动将覆盖率结果和您正在审阅的代码叠加来查看。有一天,我们对自己说,“必须找到一种自动化的方法。“一个星期后,我们有了第一个可运行的原型。其他工程师看到后,问是否他们也能拥有这样的原型。我们想确保我们为他们提供了最好的体验,所以我们开始研究这个问题。
IEEE Spectrum:你的调研结果里,你最惊讶的是什么?
Ivanković:我们感到惊讶的是,最初怀疑代码覆盖率方法,但却最终发现它很有用的人数非常多。我们调查的一些人基本上是反对覆盖率的,但他们仍然承认他们有时使用覆盖率方法,并且发现它很有用。
IEEE Spectrum:你在调研中面临的最大挑战是什么?你是如何克服的?
Ivanković:从表面上看,代码覆盖率似乎是一个简单的概念:即一行代码是否被测试覆盖。但事实证明,当大规模实施时,它充满了各种边角情况和意外情况。我们花了几年的时间,来修复测试的基础设施中的所有失败情况。
我们在进行研究时遇到了类似的挑战。我们调查的大多数工程师对覆盖率的总体概念是一样的,但当被问及细节时,他们的回答却大相径庭。我们必须对一小部分人群进行几次调查,才能得到正确答案。
IEEE Spectrum:您认为谷歌的代码覆盖基础设施有哪些优势?你认为还有什么可以改进的?
Ivanković:我们努力确保基础设施资源是有效利用的,并且可以运行在谷歌如此大的代码规模上。向人们展示这是可能的,这可能是(我们的研究)最大的贡献。
我们设计我们的基础设施,以更容易地进行实验、做 A /B 测试和评估假设。我们还以可访问的格式导出所有数据,这样覆盖率信息就可以可视化,这有助于团队保持健康的代码,并准备好修复事件。
当我们在调查工程师的时候,他们中的一些人给了我们改进的建议,其中一些建议值得我们去探索。其中一个比较有趣的方法是,如果代码覆盖率测试结果太好,就不要显示它们,这样工程师就不会过于自信。
IEEE Spectrum:对于希望部署代码覆盖率,或改进现有代码覆盖率的软件开发和测试团队,您有什么建议?
Ivanković:我认为可以给到的最重要的建议,是专注于他们的工作流程。不要只是部署覆盖率测试,还要确保您将其集成到开发人员工作流的正确位置,只有在这个位置上,覆盖率结果才是最有用的。在我们的经验中,代码评审是代码健康的基石。
IEEE Spectrum:对于谷歌的代码覆盖基础设施,未来将会有什么发展?
Ivanković:目前,我们在更进一步地研究数据使用和开发人员的意见,以便更好地理解如何使用覆盖率。例如,我们正在研究,人们理解到的有用性与实际的有用性之间的差异。我们想要研究的一个具体问题是,“在代码评审期间,显示覆盖率实际上会加快评审过程吗?”这项研究的结果,将决定我们下一步的基础设施如何改进。