代码覆盖工具如何工作?

Han*_*sir 54 code-coverage

像NCover这样的代码覆盖工具如何知道代码的哪些部分被执行以及哪些部分没有被执行?

Ira*_*ter 16

这是一篇关于如何为任意语言实现测试覆盖率工具的技术论文.

我的公司基于这个原则为Java,C#,C++,PHP,COBOL,PLSQL ......构建了一系列测试覆盖工具.


Han*_*son 8

直接引用NCover FAQ:NCover报告在整个自动化测试过程中代码中分支的百分比.它通过在每个分支处检测源代码并将"命中"点写入文件来实现此目的.然后将这些"命中"点与可能被"击中"的总可能点进行比较.

  • @Yassir:你可能想澄清一下你的问题.但是,由于NCover是开源的,你已经可以看到它是如何做到的......我建议你看看你是否可以查看尽可能早的版本,其代码可能会更少,因此应该向你展示结构更轻松. (8认同)

Pet*_*ete 7

这个来源:

NOver 使用 .NET Framework 分析器 API 来监视应用程序的执行。当 CLR 加载方法时,NCover 检索 IL 并将其替换为经过检测的 IL 代码

简而言之,它将自己挂接到即时编译中。

但并非所有工具都以相同的方式工作。其他工具的工作原理是在代码编译后修改应用程序的字节码。


Tom*_*han 5

它要求您在启用代码覆盖率分析的情况下运行一次测试,然后简单地计算所覆盖的块(即范围块)的数量,并与您正在测试的项目中的块总数进行比较。

基本推理是,如果覆盖了代码块的每种可能的组合,则所有代码路径都被覆盖了1。反对过分重视代码覆盖率数字的主要论点是,像 getter 和 setter 这样的“简单”块,它们没有提供任何实际价值(并且几乎不会出错......)与更容易出错的代码块一样重要。


1) 正如Ira Baxter在评论中指出的,这句话之前的措辞是不正确的。请阅读评论以对此进行一些讨论。

  • “如果每个块都被覆盖,那么所有代码​​路径都被覆盖”。错误的。想象一下四个块,两对 A1 A2 B1 B2,每个都由 if-theelse A 和 B 控制。假设 if 条件是独立的,则有 4 条可能的路径。有了A真,就可以锻炼B真假;将覆盖 A1 B1 B2。当 A 为假且 B 为假时,A2 和 B2 被覆盖。通过到目前为止描述的一组测试,A1 A2 B1 B2(所有块)都被覆盖了。但路径A2 B1还没有被执行。并非所有路径都被覆盖。块/分支覆盖!=路径覆盖。 (4认同)
  • @Brenden:通常除了你之外还有其他人定义“足够好”的标准。有些人会满足于“每个块至少执行一次”;这本质上是“分支机构覆盖”。有些人坚持认为任何布尔表达式的每个因果子条件都被涵盖;这就是飞机软件如此出色的原因(DO-178B)。其他人可能坚持认为所有路径都已覆盖。关键是有很多标准,每个标准都有不同的受众。他们告诉你什么是可以接受的,而不是相反。 (3认同)

Sha*_*lde 5

我知道这是一个老问题,但如果您仍然感兴趣,您可以通过查看开源项目OpenCover来查看如何为 .NET 应用程序执行此类检测的示例。

OpenCover 在代码中的重要点插入检测点。

  1. 对于代码行覆盖,它使用从PDB文件中获取的序列点
  2. 对于分支覆盖,它通过检测跳转目标和分支指令之后的下一条指令来检测 COND_BRANCH 指令,即没有跳转。
  3. 对于方法检测,它检测任何方法的第一条指令。

在使用 Mono.Cecil 定位适当的点并从控制台主机传递到分析器后,所有这些规则都将应用于CoverageInstrumentation.cpp

PartCover 的源代码也可用(如所示),但这很难遵循,但它也使用来自 PDB 的序列点来确定它在哪里检测代码。