代码评审
代码评审通常由作者之外的人评审代码,在代码引入代码库之前进行。代码评审通常需要一个流程和支持该流程的工具。
在谷歌,基本上每一个变更在提交前都需要经过代码评审,每一个工程师都需要负责发起评审和评审变更。
01 代码评审流程
代码评审可以在软件开发的许多阶段进行。在谷歌代码评审发生在变更提交到代码库之前,这个阶段也称为提交前评审。
代码评审的最终目的是让另一个工程师同意变更,我们通过标记变更为 “看起来不错”(looks good to me, LGTM) 来表示这一点。
我们将此LGTM 用作一个必要的许可 “项〞来允许提交变更。
谷歌的一个典型代码评审流程包括以下步骤:
作者在其自己的工作区中编写代码变更。然后,作者创建一个变更的快照:一个补丁和相应的描述,并上传到代码评审工具中。此变更生成与代码库的差异,用于评估哪些代码发生了变更。
作者可以对这个初始补丁进行自动化评审,或者自我评审。当作者对变更的差异感到满意时,将变更邮件给一个或多个评审人员。这一步将通知那些评审者,请他们查看快照并对其进行评审。
评审者在代码评审工具中打开变更,并在差异处发表评论。有些评论要求明确解决,有些只是提供建议。
作者根据反馈意见修改并上传新的快照,并回复给评审人员。步骤3和步骤4可以重复多次。
评审人员对变更的最新状态感到满意后,他们同意该变更,并通过标记它为“看起来不错(LGTM)来接受该变更。默认情况下,只需要一个LGTM,尽管惯例可能要求所有评审人员同意更改。
标记为 LGTM 的变更,允许作者将变更提交到代码库中,前提是他们解决了所有代码评审的意见,并且变更被批准了。
02 代码评审的好处
谷歌几乎要求对代码库的每一个代码变更都进行代码评审,不管变更有多小。
这项任务确实会对工程速度产生成本和影响,因为它确实会减慢将新代码签入代码库的速度,并且会影响任何给定代码变更发布到生产环境的时间。(这两个都是软件工程师对严格的代码评审流程常见的抱怨理由。)那么,为什么我们需要这个流程呢?为什么我们认为这是一个长期的好处呢?
设计良好的代码评审流程和认真对待代码评审的文化提供了以下好处:
- 检杳代码正确性。
- 确保代码可读性。
- 增强代码库一致性。
- 促进团队责任感。
- 进行知识共享。
- 提供代码评审本身的历史记录。
随着时间的推移,这些好处中有许多对软件组织至关重要,其中许多不仅对作者有益,而且对评审者也有益。
03 如何进行代码评审
在谷歇,对于任何给定的变更,代码评审有三个方面需要 “批准”:
来自另一个工程师的正确性和理解性检查,以确保代码是适当的,并且代码的表现跟作者描述的是一样的。这通常是同一个团队的成员,虽然不一定是。这反映在 LGTM 许可“项”中,在同行评审同意代码“看起来不错”后,将设置该许可。
来自代码所有者之一批准,确保代码适合于代码库的这一特定部分,并且可以签入到特定的目录中。如果作者就是所有者,这种批准可能是隐含的。谷歌的代码库是一个树状结构,每个目录都拥有特定的所有者。所有者充当他们特定目录的看门人。任何工程师都可以提出变更,并且 LGTM 也可由任何其他工程师提出,但是相关目录的所有者也必须批谁才能将变更添加到其目录中。这样的所有者可能是技术主管,或者是代码库特定领域的专家。通常由每个困队来决定是充泛还是狭隘地分配所有权。
来自具有语言可读性认证的人的批准,确保代码符合语言的风格和最佳实践,并检查代码是否以我们期望的方式编写。 同样,如果作者具有这样的可读性认证,这种认可也可能是默认的。这些工程师是从全公司范围内的工程师中挑选出来的, 他们被授子了该编程语言的可读性认证。
虽然这种级别的控制听起来很麻烦,但是,不可否认,有时候大多数评审都是由同个人承担了这三种角色,这大大加快了评审流程。重要的是,作者也可以承担两种角色,只需要从另一个工程师那里得到一个 LGTM,就可以将代码签入到代码库中,前提是他们已经具有该语言的可读性认证。
这些要求使得代码评审流程非常灵活。
一个技术主管,他是一个项目的所有者,并且具有代码语言可读性认证,他可以提交代码变更,且仅需要另一个工程师的LGTM。没有这种权限的实习生可以向同一代码库提交相同的变更,但必须得到具有语言可读性认证的所有者的批准。
上述三个许可项可以任意组合。作者甚至可以向多个不同的人请求多个LGTM,方法是显式地标记变更为希望所有评审者的LGTM。
在谷歌,“可读性”不只是指理解,而是指使得其他工程师能够维护代码的一套风格和最佳实践。
可读性评审人员: 这些工程师是从全公司范围内的工程师中挑选出来的, 他们被授子了该编程语言的可读性认证。
在实践中,大多数需要多个审批的代码评审通常要经过两个步骤。
从同行工程师那里获得LGTM,然后向适当的代码所有者/可读性评审人员寻求批准。
这使得这两个角色可以专注于代码评审的不同方面,并节省评审时间。主审人可以关注代码的
正确性和代码变更的, 总体有效性,代码所有者可以关注该变更是否适合签入代码库,换向话说,代码所有者经常会寻找与同行评审者不同的内容。毕竟,有人正在尝试将代码签入到他们负责的项目/目录。他们更关心这样的问题:
这个代码维护起来是容易,还是困难?”
它是否增加了我的技术债务?
我们困队是否有专业知识来维护它?
如果这三种类型的评审都可以由一个评审者来处理,为什么不能让这些类型的评审者处理所有代码评审呢?简短的答案是规模。分离这三个角色为代码评审流程增加了灵活性。
如果你在公用程序库中与同行一起开发一个新函数,你可以让团队中的某人检查代码的正确性和理解性。
经过几轮(可能要花几天时间)后,你的代码满足了同行评审者的要求,并获得了 LGTM。
现在,你只需要让库的所有者(并且通常具有适当的可读性认证的所有者)来批准变更。
04 代码评审最佳实践
礼貌且专业
所有代码在合并到代码库的时候就属于整个团队的,代码不代表个人,评审者应该尊重作者对特定方案的意见,只有在作者实现方案有缺陷时,才提出替代性方案.
最小变更
保持代码评审流程灵活的关键可能是保持小的变更.
理想的情况是:无论是评审者还是作者个人来说,代码评审应该易于理解,仅关注单个问题.
小的变更通常应该限制在 200 行代码以内。
保持小的变更是的评审人员可以更快地判断并批准任何变更。
清晰的变更描述
变更描述应该在第一行以摘要的形式说明变更的类型。毕竟第一行是黄金区域,用于在代码工具中提供摘要。
在编写公共 API 时,代码注释同样重要。
评审人员数量最小化
谷歌的大多数代码评审都是一个评审人来完成的。由于代码评审流程容许代码的正确性、代码库所有者接纳和语言可定性由一个人处理,所有代码评审流程在谷歌这种大规模的组织中很好的扩展。
自动化
利用代码检测工具:静态分析工具、Lint 等代码规范工具。
05 总结
代码评审是谷歌中最重要和关键的流程之一。
代码评审充当工程师之间的纽带,代码评审是开发人员的主要工作流程,几乎所有其他过程都依赖与此,从测试到静态分析到CI。
一个代码评审流程必须能适当的拓展
因此,最佳实践:包括小的变更,快速的反馈和迭代,对于维持开发人员的满意度和适当的生产速度是很重要的。
- 代码评审有很多好处,包括确保代码的正确性、理解性和代码库的一致性。
- 总是通过别人来检查你的假设,为读者优化。
- 提供批评反馈的机会,同时保持专业性。
- 代码评审对于整个组织的知识共享非常重要。
- 自动化对于扩展流程至关重要。
- 代码评审本身提供了历史记录。