代码覆盖率测量
学习目标
-
了解代码覆盖率指标
-
生成和检查代码覆盖率报告
-
找到尚未被自动化测试覆盖的代码
-
强制执行代码覆盖率阈值和提高代码覆盖率
代码覆盖率(也称为测试覆盖率)告诉您通过运行单元测试和集成测试来执行的代码部分。代码覆盖率通常以百分比形式表示,例如,79%语句,53%分支,74%函数,78%行数。
语句广义上是控制结构,例如if
和for
,以及由分号分隔的表达式。分支是指 if (…) {…} else {…}
和 … ? … : …
条件的两个分支。函数和行不言自明。
覆盖率报告
在Angular的Karma和Jasmine设置中,使用 伊斯坦布尔(Istanbul) 来测量测试覆盖率。Istanbul重写要测试的代码,记录是否调用了语句、分支、函数和行。然后它生成一个全面的测试报告。
要在运行测试时激活Istanbul,请添加--code-coverage
参数:
ng test --code-coverage
在测试完成后,Istanbul会将报告保存在位于Angular项目目录下的coverage
目录中。
该报告是一组HTML文件,您可以使用浏览器打开。首先,在您选择的浏览器中打开coverage/index.html
文件。
Flickr搜索示例的报告如下所示:

Istanbul为每个目录和每个文件创建了一个HTML页面。通过跟随链接,您可以查看每个文件的报告。
例如,Flickr搜索的 photo-item.component.ts 的覆盖率报告如下:

报告呈现了带有调用次数信息的源代码注释。在上面的示例中,除了一个不相关的else
分支(用“E”标记)之外,代码完全被覆盖。
规范 it('focusses a photo on click', () ⇒ {…})
在点击照片项来测试focusPhoto
输出是否发出。让我们故意禁用这个规范,以查看影响。

从上面的覆盖率报告中可以看出,handleClick
方法从未被调用过。一个关键的组件行为没有进行测试。
如何使用覆盖率报告
现在我们知道如何生成报告,那么我们应该如何使用它呢?
在章节 适量的测试 中,我们已经确定了代码覆盖率作为一个有用但存在缺陷的度量标准。作为一种定量的指标,代码覆盖率无法评估测试的质量。
软件测试不是一场竞赛。我们不应该为了得分而努力达到某个特定的分数。那么我们测量代码覆盖率的目的是什么呢?
找到未覆盖的代码 |
覆盖率报告是一个有价值的工具,你在编写测试时应该使用它。它 揭示了尚未进行测试的代码行为。该报告不仅指导您的测试,还加深了您对测试工作原理的理解。
无论您当前的覆盖率得分是多少,都可以使用报告来监控和改进您的测试实践。如 定制您的测试方法 中所述,测试应该是开发例程的一部分。新功能应包括测试,错误修复应包括一个测试作为证明和防止回归的手段。
提高覆盖率 |
编写新代码和修改现有代码不应降低覆盖率得分,而是逐步增加。这意味着如果您现有的测试覆盖了75%的代码行数,新代码需要至少有75%的覆盖率。否则,得分会逐渐下降。
在持续集成环境中运行单元测试和集成测试,并测量代码覆盖率是常见做法。为了强制执行特定的覆盖率得分并防止下降,您可以在 Karma配置 中配置阈值。
在karma.conf.js
中,您可以为语句、分支、函数和行添加全局阈值。
coverageReporter: {
/* … */
check: {
global: {
statements: 75,
branches: 75,
functions: 75,
lines: 75,
},
},
},
在上述配置中,所有的值都设置为75%。如果覆盖率低于这个数字,即使所有的规范都通过了,测试执行也会失败。
提高标准 |
当新的代码添加到项目中,并且测试覆盖率优于平均水平时,您可以逐渐提高阈值,例如从75
提高到75.1
、75.2
、75.3
等等。很快,这些小的改进将累积起来。
测试覆盖率不应该是一个毫无意义的竞争,它给开发人员带来压力,并让那些未达到任意标准的人感到羞耻。测量覆盖率应该是一个可以为您自己获益的工具。请记住,编写有意义、准确的测试并不一定会增加覆盖率得分。
对于初学者和专家来说,覆盖率报告有助于设置、调试和改进他们的测试。对于经验丰富的开发人员,得分有助于保持稳定的测试实践。