现在,软件行业的大多数组织都已采用持续集成,我们已准备好迎接下一个挑战:质量门。持续集成为我们带来了高度自动化的软件交付。这是一件好事,除非这些交付的质量不够好。最合乎逻辑的下一步是在这些交付之前设置一个门或一组门,这将防止发布不良软件。在本指南中,我们将根据多年在这方面的经验,解释如何以最有效的方式设置软件质量门。糟糕的质量门会给组织带来很多挫败感,因此建议从一开始就做好。
第一个位置,即在开发过程中的拉取请求,是最流行和最知名的位置。它非常有效,因为它处于开发过程的早期,但也有一些重要的注意事项。作为拉取请求的一部分,质量门应该快速、强大且易于修复。让我们更详细地看看这 3 个约束:
第二个位置在软件开发过程的稍晚一些。这是在交付之后,在夜间构建期间。在这个位置,时间压力较小,这意味着我们可以专注于要检查的较慢的指标。在这个位置最重要的约束是额外的检查应该有很多附加值,因为如果这个门失败了,它将在工程师交付后的一天或多天返回给他。必须有非常好的理由在游戏后期要求修复。一个例子可能是深度流分析,它识别了内存泄漏或空指针异常,即难以用快速工具检测到的致命错误。
总之,快速、稳健且易于修复的指标应该成为拉取请求质量门的一部分,而缓慢但极其强大的指标应该成为夜间构建门的一部分。
质量控制可以通过绝对目标或相对目标来实现。绝对目标是一个不能超过的阈值,例如,完全不允许出现编译器警告,或者代码覆盖率不能低于 60%。绝对目标很容易使用,因为它们通常很明确而且目标远大。然而,在大多数情况下,它们在实践中效果并不好。假设您有很多遗留代码,例如,很多现有的编译器警告。您首先需要解决不是您自己造成的现有问题,然后才能交付。修复不是您自己造成的问题是一种风险,因为您可能不知道这些问题为什么会出现在代码中。另一个缺点是绝对目标可能不会带来改进。如果您的代码覆盖率是 65%,而 60% 是绝对目标,那么您就没有经过像样的单元测试就可以交付代码。
2
另一方面,相对目标对每个人来说都是一件好事。工程师只需要修复自己引入的问题,这近似于著名的软件童子军规则:你应该让代码比你发现时更好。管理层也接受这种方法,因为它可以最大限度地减少工作量和风险。不要做不必要的修饰,只需修复在变更过程中出现的问题。
总而言之,相对目标才是可行之道。
另一方面,相对目标对每个人来说都是一件好事。工程师只需要修复自己引入的问题,这近似于著名的软件童子军规则:你应该让代码比你发现时更好。管理层也接受这种方法,因为它可以最大限度地减少工作量和风险。不要做不必要的修饰,只需修复在变更过程中出现的问题。
总而言之,相对目标才是可行之道。
现在我们知道了在哪里以及如何进行质量门控,剩下的问题是:我们要用什么指标来衡量质量门控?这似乎相当复杂。假设您有复杂的代码,并且有一个绝妙的想法,即在循环复杂度上设置一个相对阻塞质量门控,这是一种很好的方法,可以使代码随着时间的推移变得更简单。您的想法可能不会像您预期的那样:有一天会在软件中检测到一个错误,而修复方法是添加一个额外的“if”语句。现在您有麻烦了,因为您不被允许交付此更改,因为这会增加复杂性。换句话说:您已经修复了一个错误,但 质量门控失败了。这不是我们引入质量门控的原因。
3
但它变得更加复杂。假设你决定对代码覆盖率进行质量门控。每次你交付更改的代码时,你的单元测试都必须变得更好。有一天,你被要求从代码中删除一个旧的未使用的功能。结果是你删除了很多代码。如果旧代码的代码覆盖率很高,那么你将无法通过门控,因为由于你的更改,平均值从 75% 下降到了 74%,即使你通过删除旧内容改进了代码。经验表明,真正符合要求的指标是基于违规的指标。基于违规的指标的例子有编码标准违规、编译器警告和安全问题。优点是,如果你删除一些代码,不会增加违规的数量。如果你更改了一些代码,你是唯一引入新代码的人,所以你完全可以控制并承担全部责任。总之,选择基于违规的指标来对质量门控进行质量门控。
除了上面讨论的权衡之外,还有一个决定需要做出。质量门是阻塞性的还是仅提供信息?这两种门都有各自的优点和缺点。信息性或软性质量门总是让工程师通过。没有人会感到烦恼或被阻拦。缺点是质量下降会悄悄地溜走。硬性或阻塞性门是无情的,但它们可以确保改进。我们看到,人们应该总是从软门开始熟悉这个概念,但迟早门应该变成硬门。否则,你就没有认真对待自己。
质量门是提高软件质量的好方法。在本指南中,我们讨论了引入此类门的方法以及一些注意事项。我们强烈建议为违规指标设置阻塞/硬质量门。如果它们快速且易于修复,请将它们作为拉取请求的一部分。如果它们需要更多时间,请将它们作为夜间构建的一部分。即使是这种经过验证的质量门策略有时也有缺陷。假设您遇到误报。在这种情况下,阻塞门将无情地阻塞。幸运的是,我们也为这种情况提供了一些创可贴,即所谓的“豁免流程”,但那是另一回事了。