Close

什么是代码覆盖率?

在本文中,您将了解如何开始使用代码覆盖率、找到合适的工具以及如何计算代码覆盖率。

Sten Pittet 头像
Sten Pittet

特约作家


代码覆盖率是一项指标,可以帮助您了解测试了多少源代码。这是一个非常有用的指标,可以帮助您评估测试套件的质量,我们将在此处介绍如何开始您的项目。

代码覆盖率是如何计算的


代码覆盖率工具将使用一个或多个标准来确定在执行测试套件期间您的代码是如何执行的。覆盖率报告中的常见指标包括:

  • 函数覆盖率:已定义的函数中有多少被调用。
  • 语句覆盖率:程序中有多少语句已执行。
  • 分支覆盖率:控制结构的分支(例如 if 语句)中有多少已执行。
  • 条件覆盖率:已经测试了多少布尔子表达式的真值和假值。
  • 行覆盖率:已经测试了多少行源代码。

这些指标通常表示为实际测试的项目数量、代码中找到的项目以及覆盖率百分比(测试的项目/找到的项目)。

这些指标是相关的,但又是不同的。在下面的简单脚本中,我们有一个 Javascript 函数检查参数是否是 10 的倍数。稍后我们将使用该函数来检查 100 是否是 10 的倍数。这将有助于了解功能覆盖率和分支覆盖率之间的区别。

查看解决方案

使用 Open DevOps 构建和操作软件

相关资料

DevOps 的自动化测试

coverage-tutorial.js

function isMultipleOf10(x) {   if (x % 10 == 0)     return true;   else    return false; }   console.log(isMultipleOf10(100));


我们可以使用覆盖率工具 istanbul 来查看运行此脚本时执行了多少代码。运行覆盖率工具后,我们会收到一份显示覆盖率指标的覆盖率报告。可以看到,虽然我们的函数覆盖率为 100%,但我们的分支覆盖率仅为 50%。还可以看到,istanbul 代码覆盖率工具没有计算条件覆盖率指标。

在命令行中获取覆盖率报告

这是因为当我们运行脚本时,else 语句没有被执行。如果我们想获得 100% 的覆盖率,我们只需添加另一行,本质上是另一个测试,以确保使用 if 语句的所有分支。

coverage-tutorial.js

function isMultipleOf10(x) {   if (x % 10 == 0)     return true;   else     return false; }   console.log(isMultipleOf10(100)); console.log(isMultipleOf10(34)); // This will make our code execute the "return false;" statement.  


现在,我们的覆盖率工具的第二次运行将显示,由于我们底部的两个 console.log () 语句,100% 的源代码已被覆盖。

在所有标准中都达到 100% 的覆盖率

在本示例中,我们只是在终端中记录结果,但是当您运行测试套件时,同样的原则也适用。您的代码覆盖率工具将监视测试套件的执行,并告诉您在测试中运行了多少语句、分支、函数和行。

istanbul for Javascript 显示每条路径的详细覆盖率报告

代码覆盖率:六大入门技巧


1. 为您的项目找到合适的工具

根据您使用的语言,您可能会找到多种创建覆盖率报告的选项。下面列出了一些流行的工具:

工具的比较也可以帮助您做出决定。一些工具(例如 istanbul)会将结果直接输出到您的终端,而其他工具则可以生成完整的 HTML 报告,让您探索代码的哪一部分缺乏覆盖率。

2. 您的目标覆盖率百分比应该为多少?

代码覆盖率没有灵丹妙药,如果应用的关键部分没有经过测试,或者如果现有测试不够强大,无法提前正确捕获故障,那么即便覆盖率很高,也仍然会出现问题。尽管如此,人们普遍认为 80% 的覆盖率是一个很好的目标。试图达到更高的覆盖率代价可能较为高昂,但是却无法产生相应的好处。

第一次运行覆盖率工具时,您可能会发现自己的覆盖率相当低。如果您刚开始测试,这是正常情况,无需立即达到 80% 覆盖率。这是因为匆忙实现覆盖率目标可能会促使您的团队编写能够满足每一行代码的测试,而不是根据应用的业务需求编写测试。

例如,在上面的示例中,我们通过测试 100 和 34 是否是 10 的倍数,达到了 100% 的覆盖率。但是,如果我们用字母而不是数字来调用函数呢?我们会获得对的/错的结果吗?还是我们会获得例外?重要的是,要给团队留出时间,让他们从用户的角度考虑测试,而不仅仅是看几行代码。代码覆盖率不会告诉您源代码中是否缺少内容。

3. 先把重点放在单元测试上

单元测试包括确保应用使用的类和组件的各个方法都能正常工作。它们通常实施起来很实惠,运行速度很快,可以在总体上保证平台拥有坚实的基础。快速提高代码覆盖率的一种简单方法是从添加单元测试开始,顾名思义,它们应该可以帮助您确保测试套件覆盖所有代码行。

4. 使用覆盖率报告来识别测试中的重大失误

很快,您的代码中就会很多测试,以至于您无法知道在执行测试套件的过程中检查了应用的哪一部分。当您得到一个失败版本时,您会知道出现了什么问题,但是您很难知道哪些组件通过了测试。

这种情况下,覆盖率报告可以为您的团队提供可操作的指导。大多数工具都允许您深入研究覆盖率报告,以查看测试未覆盖的实际项目,然后使用它来确定应用中仍需要测试的关键部分。

SimpleCov for Ruby 显示哪些方法尚未经过测试

5. 准备就绪后,让代码覆盖率成为持续集成流程的一部分

建立持续集成 (CI) 工作流程后,如果覆盖率不够高,则开始可能测试失败。当然,正如我们之前所说,将失败阈值设置得过高是不合理的,90% 的覆盖率很可能会导致您的构建失败很多次。如果您的目标是 80% 的覆盖率,可以考虑将故障阈值设置为 70%,以此作为您的 CI 文化的安全网。

再说一遍,请注意避免发送错误的消息,因为强迫您的团队达到良好的覆盖率可能会导致不良的测试实践。

6. 良好的覆盖率并不等于好的测试

要建立良好的测试文化,首先要让您的团队了解当有人正确使用应用时,以及有人试图破坏应用时应该如何运行。代码覆盖率工具可以帮助您了解接下来应该将注意力集中在哪里,但它们不会告诉您现有的测试是否足够强大,能够应对意外行为。

实现较高的覆盖率是一个很好的目标,但它应该与拥有一个强大的测试套件相结合,该套件可以确保个别类不会被破坏,并验证系统的完整性。

您可以在此处了解有关不同类型的软件测试的更多信息。Atlassian 的 Open DevOps 还提供了一个开放的工具链平台,允许您使用自己喜欢的工具构建基于 CD 的开发管道。通过我们的 DevOps 测试教程了解 Atlassian 和第三方工具如何将测试集成到您的工作流程中。

Sten Pittet
Sten Pittet

我从事软件行业已有 10 年了,担任过从开发到产品管理的各种职务。过去五年,我在 Atlassian一直从事开发人员工具方面的工作,现在在写关于构建软件的文章。在工作之外,我喜欢与我的孩子一起共度美好时光。


分享这篇文章

推荐阅读

将这些资源加入书签,以了解 DevOps 团队的类型,或获取 Atlassian 关于 DevOps 的持续更新。

Devops 示意图

DevOps 社区

Devops 示意图

阅读博客文章

地图插图

免费试用

注册以获取我们的 DevOps 新闻资讯

Thank you for signing up

后续内容
持续部署