我们花了数十年的时间在各种大型软件公司中推动软件测试计划。其中,使用代码覆盖率数据来评估风险和测试效果,是我们一直提倡的一种方式。但是,代码覆盖率的价值一直备受争议,并且观点呈两极分化。当在一些大型讨论中抛出代码覆盖率的议题,似乎都会导致无休止的争论。而大家站在各自角度,往往会使讨论无法产出富有成效的结论。本文的目的是给出所有关于代码覆盖率的分析,以便读者可以找到有共鸣的地方,去推进覆盖率的落地。关于代码覆盖率给代码质量提升带来的帮助,我们有如下实践。
- 代码覆盖率可以为软件开发流程带来显著收益。代码覆盖率不完全代表测试质量,但是,覆盖率数据提供了合理、客观的行业标准指标。它不需要过多人为干预,适用所有软件产品,并且对大多数编程语言都有足够的覆盖率工具。读者必须认识到,覆盖率结果是大量覆盖率信息压缩而成的有损和间接指标,因此不必作为唯一判断依据。而需要将它与其他技术结合,对测试效果进行更加全面的评估。
- 单独的代码覆盖率提升是否会减少缺陷?这是一个开发的研究课题。但是我们的经验表明,从长期看它确实可以减少缺陷,因为提升覆盖率的努力可以促进质量文化建设。举一个例子,优先考虑代码覆盖率的团队会更重视测试质量,更倾向在产品设计中关注系统可测试性,从而更轻松的实现测试目标。这些反过来推进团队成员写出更高质量的代码(更好的模块化、API中更整洁的约束、更易于CR的代码等)。
- 高的代码覆盖率并不意味着高质量的测试覆盖。聚焦在将代码覆盖率提升到接近100%,会带来错误的安全感。这可能是浪费的,它消耗运行时间,而且低价值的测试只会产生大量要维护的技术债。即便进行了覆盖率分析,也可能产生测试遗漏,因为有2种情况,(a)你的测试未覆盖特定代码路径,这可以容易通过覆盖率分析识别,(b)你的测试没有覆盖特定边界场景,但覆盖率数据已包含,这就很难通过代码覆盖率分析发现。被覆盖了的代码行或者分支并不意味着它被全面的测试了,只意味着它被某个测试场景执行到了。尤其需要避免的是,为了提高覆盖率拷贝/粘贴测试用例,或者为了满足测试数量要求,增加无效的测试。为了评估测试场景和错误断言是否充分,错误注入测试是一个很好的手段。
- 但是单次部署自动化用例的覆盖率很低往往意味着大量测试场景未覆盖。这增加了推送错误代码上线的风险,应该引起注意。事实上,对于代码覆盖率尤其需要关注的不是已经被覆盖的,而是没有被覆盖的。
- 没有一个适用于所有产品的“理想代码覆盖率值”。代码函数的测试级别可能是(a)商业影响/关键代码;(b)接触或修改代码的频率;(c)你期望的代码生命周期、复杂度和域变量。我们不能要求每个团队达成x%的覆盖率要求,这是个商业决策,应该由拥有领域专业知识的经理制定。任何对覆盖率指标的要求都应该配套简化测试的基础设施,例如将工具集成到开发工作流。需要注意的是,工程师可能将覆盖率目标作为一个check点,从而避免进一步提升覆盖率,即便是这个提升可能是更明智的。
- 一般来说,很多产品的代码覆盖率都低于标准。我们应该聚焦于全面提高代码覆盖率。尽管没有“理想代码覆盖率”,在google,会将60%定位“可接受”,75%为“值得称赞”,90%为“卓越”。但是,我们尽量避免自上而下的要求,并鼓励每个团队选择适合其业务需求的覆盖率值。
- 我们不应该沉迷于如何将覆盖率从90%提高到95%。代码覆盖率超过某个临界值,持续提升的收益将会降低。但是,我们需要采取具体步骤让覆盖率从30%提升到70%,并确保新增代码覆盖率满足我们的预期阈值。
- 比代码行覆盖率更重要的是,人们对于未覆盖代码(和场景)的判断,以及对于风险是否可接受。未覆盖的代码比已覆盖的更有意义。在代码检视环节,对未覆盖代码的务实讨论,比覆盖率值超出我们随意定的指标更有价值。我们发现,结合代码覆盖率信息的代码检视,能让检视人更快更轻松。不是所有代码都同等重要,例如为了测试的调试日志代码就不太重要。因此,当开发者不仅仅看到一个覆盖率值,还包含每一行代码覆盖信息,他们就能确定重要代码是否被覆盖了。
- 你的产品拥有低的代码覆盖率并不意味着你不能采取具体的、渐进的步骤逐步改进。承接一个未经测试和可测试性很差的系统是吓人的,而且可能没有能力改变这种状态,甚至不知道从哪里开始。但是,至少你可以采取“童子军规则”(让营地比你到来时更整洁一些)。随着时间推移,情况会逐步改善。
- 确保频繁变更的代码被覆盖了。尽管90%的全局覆盖率不一定值得,但是每次提交覆盖99%的增量代码是合理的,90%可作为最低要求。我们需要确保测试不会随着时间的推移变得更差。
- 单元测试覆盖率只是其中一个难题。集成/系统测试的代码覆盖率也很重要。流水线(单测和集测)上以全局视角查看总的覆盖率是很重要的,因为它展示了在流水线到生产环境过程中,你的自动化用例有多少代码没有覆盖。你需要关注的是,单元测试中源码和测试代码有更高的关联性,而集成测试和端到端测试中某些覆盖是偶然的、非刻意的。但是,考察集成测试的代码覆盖率,能避免给你带来错误的安全感,即尽管我没有在单测中覆盖对应代码,但是我以为在集成测试中进行了覆盖。
- 我们应该限制不符合代码覆盖率要求的部署。团队应该充分讨论和确定对其有意义卡点规则。但是需要注意的是,不要将其作为一个必选框,这样只会适得其反(强行要求“达成指标”基本不会产生预期结果)。还有很多其他可用的机制:全量代码覆盖率卡点vs增量代码覆盖率卡点;统一制定一个代码覆盖率值vs关注不同版本的覆盖率变化,可忽略代码和重点关注代码的覆盖率。然后,致力于以团队方式坚持这些原则。违反代码覆盖率要求的提交将不被检入和进入生产环境。
如果你对google的覆盖率工具感兴趣,欢迎访问“Coverage at Google”
原文:https://testing.googleblog.com/2020/08/code-coverage-best-practices.html
一篇关于测试用例管理工具的介绍:https://mp.weixin.qq.com/s/8TlA8k14pdrrU8tv_A4cHQ
欢迎来到testingpai.com!
注册 关于