代码覆盖测试

代码覆盖(Code Coverage)是软件测试中的一种度量,描述源代码被测试的比例和程度,所得比例称为代码覆盖率。在做单元测试时,代码覆盖率常常被拿来作为衡量测试好坏的指标,甚至,用代码覆盖率来考核测试任务完成情况,比如,代码覆盖率必须达到80%或90%。于是乎,测试人员费尽心思设计案例覆盖代码。用代码覆盖率来衡量,有利也有弊。

度量方式

函数覆盖

函数覆盖(Function Coverage),执行到程序中的每一个函数(或副程式)。

语句覆盖

语句覆盖(Statement Coverage),又称行覆盖(Line Coverage),段覆盖(Segment Coverage),基本块覆盖(Basic Block Coverage),这是最常用也是最常见的一种覆盖方式,就是度量被测代码中每个可执行语句是否被执行到了。这里说的是“可执行语句”,因此就不会包括像C++的头文件声明,代码注释,空行,等等。非常好理解,只统计能够执行的代码被执行了多少行。需要注意的是,单独一行的花括号{}也常常被统计进去。语句覆盖常常被人指责为“最弱的覆盖”,它只管覆盖代码中的执行语句,却不考虑各种分支的组合等等。假如你的上司只要求你达到语句覆盖,那么你可以省下很多功夫,但是,换来的确实测试效果的不明显,很难更多地发现代码中的问题。

判断覆盖

判断覆盖(Decision Coverage),又称分支覆盖(Branch Coverage),所有边界覆盖(All-Edges Coverage),基本路径覆盖(Basic Path Coverage),判定路径覆盖(Decision-Decision-Path)。它度量程序中每一个判定的分支是否都被测试到。这句话是需要进一步理解的,应该非常容易和下面说到的条件覆盖混淆。

条件覆盖

条件覆盖(Condition Coverage),它度量判定中的每个子表达式结果true和false是否被测试到

路径覆盖

路径覆盖(Path Coverage),又称断言覆盖(Predicate Coverage)。它度量了是否函数的每一个分支都被执行了。 这句话也非常好理解,就是所有可能的分支都执行一遍,有多个分支嵌套时,需要对多个分支进行排列组合,可想而知,测试路径随着分支的数量指数级别增加。

代码覆盖测试工具

Codecov

Codecov网站是一个开源的测试结果展示平台,将测试结果可视化。Github上许多开源项目都使用了Codecov来展示单测结果。Codecov只是代码覆盖测试报告托管平台,一般是与Travis CI、GitHub Action等工具集成。Travis CI或GitHub Action等可以建立覆盖测试环境,在其中安装如Python的coverage等包执行覆盖测试,然后生成代码覆盖测试报告,上传到Codecov。所以实际做覆盖测试的是coverage等具体工具包,而非网站。

Python程序的覆盖测试

这里以coverage举例,也可使用pytest-cov。貌似只能做语句覆盖测试。

1
2
3
4
5
6
7
8
# 安装覆盖测试的Python包
pip install coverage

# 使用pytest做测试,使用coverage分析测试过程
coverage run -m pytest

# 报告覆盖测试结果
coverage report -m

使用Travis CI构建环境、测试以及上传到Codecov

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
dist: xenial
sudo: required
language: python
install:
- rm -rf .eggs && pip install -e .
- pip install pytest-cov
- pip install codecov
cache:
pip: true
python:
- '3.5'
- '3.6'
- '3.7'
script: python -m pytest --cov=cvtools
after_success: codecov

codecov包作用:Find coverage reports for all the languages ​​below, gather them and submit them to Codecov.

可见只是一个测试报告上传工具,GitHub上的源代码只有一个文件。

总结

通过上面的学习,我们再回头想想,覆盖率数据到底有多大意义。总结如下几个观点:

  • 覆盖率数据只能代表你测试过哪些代码,不能代表你是否测试好这些代码。
  • 不要过于相信覆盖率数据。
  • 不要只拿语句覆盖率(行覆盖率)来考核你的测试人员。
  • 覆盖强弱:路径覆盖 > 判定覆盖 > 语句覆盖
  • 测试人员不能盲目追求代码覆盖率,而应该想办法设计更多更好的案例,哪怕多设计出来的案例对覆盖率一点影响也没有。

参考

------ 本文结束------
赞赏此文?求鼓励,求支持!
0%