持续交付2.0

衡量开发人员的生产力的一个方面:软件质量

我今天和何勉老师讨论工程效能度量,谈到工程效能度量可以分成两部分。

第一部分是工程效率,也就是持续交付2.0 双环模型的右环(快速验证环)起关键作用,主要就是开发速度与质量。这主要是由工程师团队决定。

第二部分是有效性,也就近似于下文中提到的易用性。也就是持续交付2.0又环模型的左路环(价值探索环)起到关键作用。这个易用性的语言权应该在客户(用户)那里,不可能在企业内部被定义。但是,我们可以说,业务分析师(产品经理),用户体验设计师和工程师共同对交付的结果(有效性/易用性)产生重要影响。

下面是谷歌工程师发表于 IEEE的一篇文章,主要观点同上。

0

引子

开发人员的生产力有三个方面:速度、质量和产品易用性。

在本文中,我们将探讨软件质量,以及定义和衡量软件质量为何如此困难,并提出四种相互影响的质量理论。

在 Google,工程生产力部门也经常被要求帮助团队衡量不同的开发者工具和流程对生产力的影响。

这种请求的常见形式是,某个团队构建了一个新的开发者工具,并希望证明该工具可以提高开发者的速度。

1

速度、便捷、优质

然而,开发人员的速度显然不是唯一的目标;我们还想打造高质量的产品。毕竟,我们可以通过取消代码审查或测试套件来轻松提高速度。

这样做可能会让我们的开发人员速度看起来更快,但这显然不是谷歌公司的好策略。

因此,虽然我们确实希望提高速度,但我们不希望以牺牲软件质量为代价。我们也不希望以牺牲工程师为代价;我们可以通过要求每个人加班来提高速度,但这也会以短期积极收益换取长期负面影响。

我不得不说,在谷歌可能是这种情况,在其它公司就不一定是这种观点。如果不认同这种观点,那么,工作方法也会不一样。

由于这些权衡,我们衡量了开发人员生产力的三个组成部分:速度、易用性和质量。


即使我们只期望影响其中之一,也必须衡量所有三个组成部分,以确保我们不会做出意外的权衡。

这并不是一个闻所未闻的想法;微软使用 SPACE 框架,该框架有几个重叠的概念,这两个框架都起源于 2017 年 3 月的达格斯图尔研讨会,当时来自学术界和工业界的 27 名研究人员聚集在一起讨论开发人员的生产力。在那次研讨会结束时,我们得到了一组类似的组件。最后,使用哪些特定组件并不重要;重要的是认识到开发人员的生产力是一个复杂的话题,有几个相互交织的因素,我们需要衡量每一个因素,以确保我们获得生产力的完整图景。

我们将在此深入探讨其中一个要素:质量。

在这三个要素中,质量是最难衡量的,因为它也是最难定义的。

软件质量到底是什么?软件质量对不同的人来说意味着不同的东西。

对于关心业务的副总裁来说,高软件质量意味着拥有一种人们想要使用、购买并推荐给他人的产品。

对于开发人员来说,高软件质量意味着代码本身可维护且易于使用。


对于运营人员来说,高软件质量意味着站点可靠、容错且能抵御安全威胁。

这些都是关于软件质量的宝贵观点,但如果这三个角色讨论“我们将如何提高软件质量”,他们可能会在解决问题的方法和衡量成功的方法上出现分歧。

我们在谷歌也看到过这样的对话,因此我们必须让每个人都对软件质量有一个共同的理解,涵盖这些观点及其相互作用。

2

软件质量的四种类型

为了更好地理解“质量”对软件开发人员意味着什么,我们对 Google 的开发人员进行了两轮采访。在第一个系列中,我们采访了 8 位工程师关于代码质量的问题,在第二个系列中,我们采访了另外 9 位工程师关于产品质量的问题。(请注意,我们只询问了工程师对这些话题的看法;我们没有专门询问产品经理、高管或其他角色。)

在进行代码质量访谈之前,我们进行了广泛的文献综述,以了解研究如何对待代码质量。我们寻找密切相关的术语,并确定研究目标和方法,以了解研究人员对代码质量的基本理论。

例如,在“组织结构对软件质量的影响”中,Nagappan 等人探讨了有关代码所有权的指标是否可以预测已发布二进制文件中的故障;这表明他们假设缺陷率是软件质量的一个组成部分。

而在“程序复杂性指标和程序员的意见”中,Katzmarski 和 Koschke 探讨了复杂性指标是否与开发人员对修改软件的难易程度的看法相关;这表明他们假设维护是目标。

我们发现,在与代码质量相关的研究文献中经常出现的七项内容:

  1. 缺陷率

  2. 可靠性

  3. 可维护性

  4. 可测试性

  5. 复杂

  6. 可理解性(总体目的/结构的清晰度)

  7. 可读性(行/方法级别的清晰度)。

在我们的访谈中,我们首先询问工程师他们如何定义代码质量。我们还询问他们如何描述代码质量对他们自己的生产力、他们的项目、他们依赖的项目以及整个组织的影响和后果。最后,我们询问工程师前面提到的七项中的哪一个影响了他们对项目代码质量的满意度。

我们与 9 位工程师进行了一系列类似的关于产品质量的访谈。与第一组访谈一样,我们要求工程师定义产品质量。我们还提供了以下属性列表,并询问工程师它们与产品质量的关系:

  1. 满足用户需求的能力

  2. 性能和可靠性

  3. 产品复杂性

  4. 隐私和安全

  5. 创新性。

最后,我们询问工程师代码质量对产品质量的影响程度。

基于这些访谈和阅读先前关于软件质量的文献,我们创建了一个“质量理论”,该理论认为有四种类型的质量相互影响下图列出了每种类型的质量指标的非详尽列表。虽然还有其他主要影响因素,并且这些类型的质量也会影响开发过程的其他方面,但我们可以推测它们具有所示的关系。

Image一种将“软件质量”分为四种成分类型的理论。箭头表示影响的方向:流程质量被认为会影响代码质量

3

流程质量

我们的理论是,一切都始于高质量的开发过程。高质量过程的信号包括进行全面和确定性的测试、彻底的代码审查、组织一致性和有效的规划过程。有充分的证据表明,这些措施可以预测整体软件质量;多项研究表明,基于流程的指标比现有的代码质量指标更能预测发布后的缺陷。

我们的理论是,当一个组织拥有更高的流程质量时,它确实会带来更高的代码质量,但也许现有的“代码质量”指标并没有捕捉谷歌用AI机器人大规模删除代码(二十多年积累了数十亿行,已删除 5% C++代码)到代码质量的根本现象。

因此,研究文献捕捉的是流程质量对系统质量的影响。

5

代码质量

实现更高流程质量的全部意义在于拥有更高的代码质量。

但是, 什么是代码质量?

我们参与代码质量访谈的所有八位参与者都将代码质量定义为主要与可维护性有关,并且他们将可测试性、可理解性、复杂性和可读性视为可维护性的子类别。

这与 Börstler 等人最近发表的一项关于开发人员对代码质量的看法的研究一致。他们对 34 名开发人员的访谈发现了几乎相同的结果。

总体而言,我们的开发人员将代码质量描述为代码的易用性和易理解性,以便他们可以轻松对其进行更改。

开发人员指出,对于高质量的代码文件,“您可以立即知道它要做什么”,并且“它整齐地组织成文件,每个文件都有自己的逻辑。”

  • 当开发人员看到高质量的代码时,他们会看到具有明确目的的代码;

  • 代码为开发人员提供了一个单一而连贯的思维模型。

  • 这种清晰度使得代码易于理解,并且易于后期修改。

代码质量对可靠性和缺陷减少的影响则更为微妙;只有一半的参与者表示这两者之间存在关联。另一半则指出,其他因素也可能影响可靠性和缺陷率(“即使没有错误,代码也可能因为外部因素而崩溃”),或者可靠性甚至可能根本不完全取决于代码质量(“我见过很多质量差但可靠的代码。”)

他们表示,虽然这两者之间存在关联,但它们与“代码质量”并不是同一个概念。

开发人员指出,代码质量的影响是双重的;虽然它通过减少缺陷和提高可靠性来提高系统质量,但高代码质量也会提高自身的速度。


可维护性尤其重要,因为正如一位开发人员所说,“代码只写一次,但要读很多次——系统内的每个人都必须理解并能够对其进行更改。”

我们以前也看到过这种联系;在之前的研究中,我们发现开发人员对代码质量的看法是他们后来对开发人员速度的看法的早期指标。11这很有趣,因为它强调了我们生产力的三个要素(速度、易用性和质量)并不总是严格地相互权衡;在某些情况下,它们还可以相互放大。

6

系统质量

系统质量是我们从“开发人员眼中的质量”转向“企业眼中的质量”的地方。

大多数开发人员听到“软件质量”时会想到他们的代码和流程质量,但当你与高管和产品经理交谈时,他们会更关心产品质量。(这一见解来自与高管和产品经理的随意讨论,而不是访谈研究。)

这两个观点在系统质量上汇聚在一起,事实上,我们已经看到,谷歌这两个群体之间的大多数讨论都集中在系统质量上。


然而,这两个观点可能会导致脱节;这可能导致工程主管要求更高的产品质量(因为他们想提高客户满意度),然后当软件开发人员通过改进代码的模块化来回应时感到惊讶。

虽然我们假设这些是通过系统质量联系在一起的,但这种联系对双方来说并不明显;双方只考虑了自己一半的工作。

高质量的系统具有高可靠性、高性能和低缺陷率。

高代码质量是高系统质量的必要条件,但安全性和隐私等因素实际上只能在系统级别进行衡量,它们也对整体系统质量产生影响。同样,高系统质量是高产品质量的必要条件,但不是充分条件;在产品质量层面还有其他因素在起作用。

根据我们的经验,衡量系统质量的最大困难之一是数据稀疏。


系统服务的中断是(也应该是!)非常罕见的事件。这意味着,如果一个团队在一年内只发生过两次小规模中断,而第二年没有发生过中断,那么我们就无法确定系统质量是否得到了改善。可能已经改善了,也可能是我们在测量统计噪声,而他们只是运气好而已。同样,安全威胁和隐私事件影响很大,但也非常罕见。在所有这些指标中,我们都希望指标值为“零”,但很难判断我们是否真的在单个项目上有所改进。

流程和代码质量指标可以跟踪决定系统质量的指标。无论它们是从日志中得出的经过验证的指标,还是基于工程师调查的自我报告数据,这些措施都允许工程师传达需要关注的领域以及代码健康投资的影响。


如果没有这些中间指标,利益相关者很可能会认为一年没有中断就证明系统质量很高,因为他们无法了解开发人员如何体验代码库以及代码库可能减慢他们速度的方式。

如果利益相关者将低缺陷率解释为高质量代码的保证,他们可能会鼓励更专注于推出功能以提高产品质量,而不会分配足够的资源来改进潜在的高风险系统。

在没有中断事故的一年里,可能会出现两种情况。

在最坏的情况下,开发人员可能有效地绕过各种弱点,以防止在运行不佳的系统中出现错误。

在最好的情况下,开发人员在一个缺陷风险较低的系统中工作,可以自由地专注于增强功能和迭代新功能。

如果没有代码质量指标,领导层就无法确定,他们也不知道如何指导工程工作,以确保开发人员的速度和长期的产品质量。

7

产品质量

产品质量主要由客户体验,但我们也询问了开发人员他们对产品质量的看法。

在这些采访中,开发人员确定了产品质量的三个关键因素:实用性、可用性和可靠性。有趣的是,工程师认为“创新性”是一个独特的概念,不属于产品质量。

一位工程师这样解释:“我认为质量是产品是否能很好地完成它所说的任务,而创新性就像它所说的任务一样——这是否有趣?这是否复杂?这是否……令人兴奋?”

工程师指出,他们主要对可靠性有影响,但他们与产品经理、用户体验设计师和研究人员合作,为产品的实用性和可用性做出贡献。

工程师通过两种方式将可靠性与代码质量联系起来。他们再次指出,低代码质量会降低工程速度,从而延迟产品改进,甚至使其不可行。

参与者还指出,较低的代码质量会增加缺陷风险(从而增加系统质量),从而影响产品质量。

8

质量类型之间的链接

这四种质量类型并非完全独立。如上图所示。

我们确实认为它们之间存在联系——流程质量影响代码质量,代码质量影响系统质量,系统质量影响产品质量。

研究已经表明,一些流程质量指标可用于预测缺陷率(系统质量)。然而,这些联系并不牢固,其他研究表明,预测能力在项目之间并不一致,并且随着时间的推移并不可靠。

例如,Nagappan等人12尝试使用代码质量指标来预测发布后的缺陷,但每个项目都有一组不同的预测缺陷的指标。

最令人担忧的是 Ekanayake 等人的研究,他们发现,即使对于单个项目,指标的预测价值也会随着时间的推移而显著下降。

我们的领域需要更多的研究来理解为什么我们会看到这样的结果,而我们的直觉认为质量指标应该在产品之间相同,并且对于给定的产品应该随时间保持稳定。

我们假设,这里部分问题在于现有的代码质量指标实际上并没有衡量工程师眼中代码质量的底层概念,这可能是导致这些指标无法预测系统质量的原因。例如,许多先前的研究发现,圈复杂度实际上与测量代码行数相同,以至于通过某种方式控制这种影响现在已成为研究界的标准做法。这使得圈复杂度成为代码质量的不良代理,这可能就是为什么如此多的研究发现它无法预测缺陷率或代表开发人员对复杂性的看法。

古德哈特定律:当一个指标成为唯一重要的目标时,已经不再是一个好的指标。

这只是一个例子,但考虑到这个领域的深度,在所有四种质量类型中都有很多进一步改进指标的机会。

9

技术主管要如何处理这个问题?

我们的理论提供了更细致入微的质量观,我们希望在讨论如何提高软件质量时,通过确保所有参与者都谈论同一件事,从而取得更好的结果。

如果团队试图提高产品质量,这可能确实需要提高流程质量和代码质量,但每个人都需要意识到产品质量是最终目标,并且需要明确所做的更改与产品质量之间的联系。

虽然增加测试覆盖率可能会对产品质量有一点帮助,但这种联系却很遥远。最好关注系统质量的变化(并衡量其影响)。


同时,如果团队关心代码质量,则需要考虑一组不同的指标,关注改进的流程质量可能是合理的。为提高软件质量而采取的行动——以及衡量它的指标——取决于我们想要改进哪种类型的质量。

原文链接:

https://ieeexplore.ieee.org/document/10372494