代码覆盖教程(分支、语句、决策、FSM)

任何软件开发公司的最终目标都是提供高质量的软件。为了达到这个目标,软件必须经过适当的测试。

因此,测试是软件开发过程的一个重要方面。因此,开发人员(在单元测试阶段)对生成的软件进行评估,然后将其交付给 QC 团队进行广泛测试以确保其几乎没有缺陷,这一点至关重要。

在交付给实际测试团队进行测试之前,软件会进行单元测试。此测试由开发人员完成,因为它涉及代码级别的测试。这样做是为了保证被测试代码的每个组件都能正常运行。

代码覆盖率的定义是什么?

代码覆盖率是一个衡量程序源代码测试彻底程度的指标。它是一种白盒测试,用于查找未被一组测试用例测试的软件部分。它还构建了一些测试用例以提高覆盖率并确定量化的代码覆盖率度量。

在大多数情况下,代码覆盖系统收集有关当前运行程序的数据。它还将此信息与源代码信息相结合,以提供有关测试套件代码覆盖率的报告。

为什么我们需要代码覆盖率?

由于各种原因,代码覆盖率很重要,其中一些如下所述 -

  • 与没有良好代码覆盖率的软件相比,它有助于确保软件具有更少的错误。

  • 它通过帮助改进代码质量间接地帮助交付更好的“质量”软件。

  • 它是一种可用于确定测试有效性的指标(为测试代码而编写的单元测试的有效性)。

  • 它有助于识别源代码中可能未被探索的区域。

  • 它有助于确定当前的测试(单元测试)是否足够以及是否需要额外的测试。

为什么要使用代码覆盖率?

以下是使用代码覆盖率的一些最令人信服的理由 -

  • 它帮助您确定测试实施的有效性。

  • 它提供了定量评估。

  • 它表明源代码已被测试的彻底程度。

原始源代码结构

  • 取两个值,例如a=0 和b=1。

  • 计算这两个数的总和。

  • “这是正结果”,如果总和大于 0,则打印。

  • “这是负结果”,如果总和小于 0,则打印。

方法论

在本节中,我们将介绍可以使用/可以使用的多种测量代码覆盖率的方法。

要了解这些方法,让我们看看下面的代码片段 -

Add (int a, int b) {
   if (b > a) {
      b = b - a
      print b
   }
   if (a > b) {
      b = a – b
      print b
   }
   else print '0'
}

报表覆盖

这种方法是一种衡量源代码中所有可能的可执行语句是否至少运行过一次的指标。这是一种确保每行源代码至少测试一次的技术。

虽然这似乎是一项简单的任务,但在确定报表覆盖率时务必谨慎行事。这样做的原因是基于输入值,源代码中的条件可能会或可能不会被执行。这意味着测试不会覆盖所有代码行。因此,可能需要各种输入值集来涵盖源代码中的所有此类情况。

例如,在前面的源代码中,如果输入值为 2 和 3,则不会运行代码的“Else”部分。另一方面,如果输入值是类型 3 和 2,则代码的“If”部分将不会运行。这意味着我们的语句覆盖率对于任何一组数据都不会是 100%。在这种情况下,我们可能需要使用所有三组数据 [(2, 3), (3, 2), (0, 0)] 运行测试以确保 100% 的语句覆盖率。

功能覆盖

顾名思义,这种方法测量了源代码中包含的功能在测试过程中被覆盖的程度。在测试运行期间,将测试源代码中的所有功能。同样,我们必须确保针对不同的值测试这些函数,以确保对函数进行充分测试。

一个源代码文件中可能有几个函数,根据提供的输入值,一个函数可能会被调用,也可能不会被调用。因此,Function Coverage 的目标是确保我们拥有所需的所有功能。

如果我们的测试在上面的源代码中调用了一次“添加”函数,我们会将其称为完整的函数覆盖。

条件覆盖

无论我们在源代码中的何处有条件,结果都是布尔值 true 或 false。条件覆盖的目标是查看测试是否同时覆盖真值和假值。当源代码中出现的每个条件都被评估为真和假状态时,就可以说代码的条件覆盖是完整的。

例如,如果以下代码中使用了值集 (2, 3) 和 (4, 2),则条件覆盖率将为 100%。当使用数据集 (2, 3) 时,(b > a) 变为真,(a > b) 变为假。使用数据集 (4, 2) 时,(b > a) 的计算结果为 false,但 (a > b) 的计算结果为 true。因此,这两个条件都涵盖了真值和假值。因此,条件覆盖率为 100%。

分支机构覆盖

这种方法力求确保每个条件结构的分支都在源代码中执行。例如,在前面的代码中,测试应涵盖所有“If”语句以及任何附带的“Else”语句,以实现 100% 分支覆盖率。

例如,如果在给定代码中使用了值集 (2, 3)、(4, 2)、(1, 1),则分支覆盖率为 100%。当使用数据集 (2, 3) 时,将运行第一个“If”分支并且 (b > a)。当使用数据集 (4, 2) 时,(a > b) 评估为真,这会导致执行第二个“If”分支。

然后,'Else' 分支对数据集 (1, 1) 的计算结果为真并被执行。因此,确保了 100% 的分支机构覆盖率。

分支机构覆盖的好处

以下是分支覆盖测试的一些好处 -

  • 允许您验证所有代码的分支,确保它们都不会导致程序执行中出现任何异常。

  • 分支覆盖方法消除了由于语句覆盖测试而产生的困难。

  • 允许您找到其他测试技术未涵盖的地方。

  • 它使您能够计算代码覆盖率的数值度量。

  • 分支覆盖不考虑布尔表达式中的分支。

有限状态机的覆盖范围

最困难的一种代码覆盖方法是有限状态机覆盖。这是因为它会影响设计的行为。这种覆盖方法要求您计算访问和传输的特定时间状态的数量。它还确定有限状态机包含多少个序列。

您应该选择哪种类型的代码覆盖率?

毫无疑问,这是最难做出的回应。为了选择覆盖方法,测试人员必须首先确保满足要求。

  • 被测代码中有一个或多个未检测到的错误。

  • 潜在惩罚的成本,

  • 声誉受损的代价,

  • 错过销售的成本,等等。

  • 故障越有可能导致代价高昂的生产故障,您应该选择的覆盖范围越严重。

好处

如前所述,由于以下原因,它是一个非常有价值的测试指标 -

  • 它有助于识别源代码中可能未经测试或被测试发现的部分。

  • 它可用于识别使用/死代码,从而提高代码质量。

  • 代码覆盖率可用于确定单元测试的有效性。

  • 这些测量可用于交付更高质量的软件。

缺点

  • 即使设计中没有实现某个功能,代码覆盖率仍会报告 100% 的覆盖率。

  • 代码覆盖率不允许我们判断是否测试了某个功能的所有可能值。

  • 此外,代码覆盖率并不表明您对逻辑的覆盖程度或程度。

  • 当规定的功能未实现或未包含在规范中时,基于结构的方法无法检测到问题。

代码覆盖工具

这是一个包含重要代码覆盖率工具的列表 -

工具名称和描述
1Cobertura
这是一个免费使用的代码覆盖率工具。它分析哪些代码行在测试套件运行时被执行,哪些没有被执行,并通过检测代码库来估计测试覆盖率。
2Clover
Clover 还通过仅执行涵盖自上次构建以来已更改的应用程序代码的测试来缩短测试时间。
3DevPartner
开发人员可以使用 DevPartner 检查 Java 代码的代码质量和复杂性。
4Emma
EMMA 在类、方法、行和基本块级别以及聚合源文件、类和方法级别提供覆盖。
5Kalistick
Kalistick 是一个第三方应用程序,可以从多个角度检查代码。
6CoView 和 CoAnt
编码软件是一种代码覆盖工具,可用于度量、模拟对象创建、代码可测试性以及路径和分支覆盖等。
7Bullseye for C++a
BulseyeCoverage 是一个 C++ 和 C 代码覆盖工具。
8Sonar
Sonar 是一种有助于代码质量管理的开源代码覆盖率工具。

总结

  • 代码覆盖率是一个衡量程序源代码测试彻底程度的指标。

  • 它帮助您确定测试实施的有效性。

  • 有五种不同的方法来衡量代码覆盖率。1.) 声明的覆盖范围 2.) 条件保护 3) 覆盖所有分支 4) 覆盖切换 5) FSM 的覆盖

  • 语句覆盖需要至少运行一次所有源代码的可执行语句。决策覆盖给出了每个布尔表达式的真假结果。

  • 代码模块的每个结果都在分支覆盖率中进行测试。

  • 条件语句中的变量或子表达式将以这种方式求值。

  • 最困难的一种代码覆盖方法是有限状态机覆盖。

  • 要选择覆盖方法,测试人员必须考虑潜在惩罚、声誉损失、销售损失和其他因素的成本。

  • 代码覆盖率表明您的测试平台对源代码的执行程度。术语“功能覆盖”是指设计的功能被覆盖的程度。

  • 最流行的代码覆盖工具包括 Cobertura、JTest、Clover、Emma 和 Kalistick。

  • 您可以使用代码覆盖率向覆盖率添加更多测试用例。

  • 代码覆盖率不会告诉您我们是否测试了功能的所有可能值。