我该怎样阅读伊斯坦布尔覆盖报告?

164

我一直在使用Jasmine进行单元测试,但最近开始使用Istanbul来生成代码覆盖率报告。虽然我大致了解他们试图向我传达的信息,但我并不真正知道这些百分比代表什么意思(Stmts、Branches、Funcs、Lines)。到目前为止,我通过谷歌搜索没有找到一个可靠的解释/资源。

问题:就像我说的,我大致理解它,但有人能发布一个适当的解释或一个链接到适当解释的链接吗?

第三个问题:有没有办法确定您的代码中哪些特定部分没有被覆盖?迄今为止,在没有真正理解这份报告的情况下,我基本上是在猜测。

-------------------|-----------|-----------|-----------|-----------|
File               |   % Stmts |% Branches |   % Funcs |   % Lines |
-------------------|-----------|-----------|-----------|-----------|
   controllers/    |      88.1 |     77.78 |     78.57 |      88.1 |
      dashboard.js |      88.1 |     77.78 |     78.57 |      88.1 |
-------------------|-----------|-----------|-----------|-----------|
All files          |      88.1 |     77.78 |     78.57 |      88.1 |
-------------------|-----------|-----------|-----------|-----------|

5
运行 Istanbul 应该会生成一份报告的 HTML 文件(应该位于 coverage 文件夹中)。当你点击文件/文件夹时,这个 HTML 文件应该能够提供深入信息。请注意保持原文含义,使翻译内容通俗易懂。 - Yaron Schwimmer
谢谢@yarons。这绝对有助于深入了解覆盖范围并确定具体未被覆盖的内容。但我仍然不太理解百分比的深度含义=/. - Scott Sword
4个回答

267

有多种测试覆盖准则,其中主要几种为:

  • 函数覆盖:程序中的每个函数(或子程序)是否已被调用?
  • 语句覆盖:程序中的每个语句是否已执行?
  • 分支覆盖:每个控制结构(例如if和case语句)的每个分支(也称为DD-path)是否已执行?例如,在给定的if语句中,真和假分支都已执行吗?换句话说,程序中的每条边是否都已执行?
  • 行覆盖:源文件中的每个可执行行是否已执行?

对于每种情况,百分比表示已执行的代码未执行的代码之比,每个分数以百分比格式表示(例如:50%分支,1/2)。

在文件报告中:

  • 'E'代表“else路径未采取”,这意味着对于标记的if / else语句,已经测试了“if”路径但未测试“else”路径。
  • 'I'代表“if路径未采取”,相反的情况是:“if”没有被测试。
  • 左列中的xN是该行已执行的次数。
  • 未执行的行或代码片段将以红色突出显示。

这已经验证了Istanbul v0.4.0,我不确定是否适用于后续版本,但是由于该库基于坚实的理论原则,因此行为不应在较新的版本中发生太大变化。

它还提供了一些颜色代码 -

粉色:未覆盖的语句。

橙色:未覆盖的函数。

黄色:未覆盖的分支。

完整的Istanbul文档在此处:

https://istanbul.js.org

有关代码覆盖的更深入理论:

代码覆盖率

代码覆盖率指的是在软件测试过程中,用于度量源代码中哪些部分被执行了,以及这些部分的执行次数。通常用百分比表示,是已经执行的代码行数和总代码行数之间的比例。高代码覆盖率通常意味着更全面的测试,但不能保证程序没有错误或缺陷。代码覆盖率的主要类型包括行覆盖率、分支覆盖率、条件覆盖率和路径覆盖率等。

4
我不明白的是,如何在同一个文件上既能够实现语句覆盖率达到100%,却只有不到100%的函数覆盖率。如果并没有调用所有的函数,那么如何实现100%语句覆盖率呢?例如,我的覆盖率报告中出现了这一行:“index.js | 100 | 100 | 87.5 | 100 |”,其中列的顺序为“文件|%语句|%分支|%函数|%行|未覆盖的行号”。因此,代码实现了100%的语句覆盖率,并且没有未覆盖的语句行,但只有87.5%的函数覆盖率。为什么会这样呢? - Stijn de Witt
我是从纽约得到这些结果的,但原则是相同的,对吧? - Stijn de Witt
1
这需要添加到 istanbuil.js.org 文档页面上: / - Jose

8
运行 istanbul 还会生成一份报告的 HTML 文件(应该在 coverage 文件夹中)。当你点击文件/文件夹时,此 HTML 应该提供给你分层信息。
覆盖率函数的百分比是通过测试调用的函数数除以总函数数来计算的。行和语句也是一样的(除非您有非常长的语句,这两者通常会非常接近)。 分支意味着决策点,例如 if-else 块。例如,假设你的代码只包含一个 if-else 语句,并且你的测试只通过 if 部分但不通过 else 部分,那么你的分支百分比应该是50%。
希望这能让事情更清晰明了。

我在package.json中指定了"test": "nyc mocha",并运行了istanbul。但我的覆盖率文件夹是空的。你有什么想法吗? - TheCrazyProgrammer
1
我添加了HTML报告生成器。现在它可以正常工作了。"test" : "nyc --reporter=html mocha" - TheCrazyProgrammer
例如:如果你有一个很大的if分支和一个很小的else分支,并且只运行了if分支,那么代码行覆盖率看起来很好,但分支覆盖率仍然只有50%。此外,如果语句由分号分隔或包含函数定义(其中包含其自己的语句),则每行可以有多个语句。如果语句在最终分号之前有换行符,则可以在一条语句中拥有多行。 - Hew Wolff

7

@StijndeWitt: 你问道

我不理解的是如何在同一文件中给出100%的语句覆盖率,但函数覆盖率不到100%。 如果甚至没有调用所有函数,那么如何覆盖了100%的语句?

附上的截图说明了行覆盖率可以达到100%,但函数覆盖率较低。 第3行的函数定义(F1)所在的行不计入行数,但其中显然包含一个函数。 第5行还包含一个函数(F2)和一个额外的语句。 因此,在NYC的计数方式下:

  • 行=3
  • 语句=4(其中有1个未被覆盖)
  • 函数=2(其中有1个未被覆盖)

显然,函数头不算作“行”,但它们被视为一个函数。这就解释了为什么行覆盖率可以达到100%,而函数覆盖率(或语句覆盖率)却不到100%。 Function coverage is less than 00%


0

补充前面的答案

%语句是通过测试覆盖的语句数量的百分比计算得出的,例如 12/18 * 100 = 66.67%。这意味着你的测试只覆盖了 66.67%。

%分支也是用同样的方式计算的。%函数和%行也是如此。

在你的项目根目录下,有一个包含测试 HTML 输出的 coverage 文件夹。点击它并在浏览器中查看。你应该看到类似于这样的东西

显示你测试结果输出的图像

希望这可以让你更好地理解。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接