用pytest-cov检查python的覆盖率


介绍

之前,我总结了如何使用python的pytest对烧瓶进行单元测试。
通常从是否涵盖加工路线和分支条件的angular来测试单元测试(车库测试)。我将总结如何使用称为pytest-cov的库来确定覆盖率。

环境

  • 的Python:3.6.5
  • 容量瓶:1.02
  • pytest的:5.3.5
  • pytest-cov:2.8.1

安装

  • pip install pytest安装pytest。

  • 使用pip install pytest-cov安装pytest-cov。

查看pytest-cov所需要的内容

pytest-cov基于pytest工作,因此您需要可以执行pytest的环境(要测试的源和测试源)。 pytest-cov不需要任何东西。有关如何使用pytest的信息,请参见使用pytest对烧瓶进行单元测试。

检查简单功能的单元测试的垃圾

在总结单元测试时,让我们看一下如何通过一个简单的函数使用pytest-cov。

待测试源

在总结单元测试以检查Branch时,在示例中将源与if语句一起使用。

testing_mod.py

1
2
3
4
def add_calc(a, b):
    if (a == 1):
        b = b + 1
    return a + b

描述测试方法的源

与总结单元测试时相同。

py_test_main.py

1
2
3
4
5
6
import pytest
import testing_mod

def test_ok_sample():
    result = testing_mod.add_calc(1, 2)
    assert 4 == result

运行单元测试

现在已经创建了测试目标和测试方法的源,然后执行它。根据测试是覆盖处理路径还是条件分支,执行方法略有不同。

单元测试执行涵盖了处理路径

通过在执行

pytest时添加--cov选项,可以查看处理路径的覆盖率测试速率(C0覆盖率)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# pytest --cov -v py_test_main.py

~~~~ 略 ~~~~~

py_test_main.py::test_ok_sample PASSED                        [100%]

----------- coverage: platform win32, python 3.6.5-final-0 -----------
Name              Stmts   Miss  Cover
-------------------------------------
py_test_main.py       5      0   100%
testing_mod.py        4      0   100%
-------------------------------------
TOTAL                 9      0   100%

====== 1 passed in 0.05s ======

查看结果,您可以看到要测试的testing_mod.py的覆盖率为100%,并且所有处理路径都已通过。顺便说一句,Stmts是测试期间通过的处理线数,而Miss是测试期间没有通过的处理线数。

单元测试执行涵盖条件分支

通过在运行

pytest时添加--cov --cov-branch选项,可以查看条件分支的覆盖率测试速率(C1覆盖率)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# pytest --cov --cov-branch -v py_test_main.py

~~~~ 略 ~~~~~

py_test_main.py::test_ok_sample PASSED                           [100%]

----------- coverage: platform win32, python 3.6.5-final-0 -----------
Name              Stmts   Miss Branch BrPart  Cover
---------------------------------------------------
py_test_main.py       5      0      0      0   100%
testing_mod.py        4      0      2      1    83%
---------------------------------------------------
TOTAL                 9      0      2      1    91%

====== 1 passed in 0.08s ======

从结果来看,Branch和BrPart与以前相比有所增加。这次,testing_mod.py为83%,因为我们仅测试输入if语句的条件。顺便说一句,Branch是条件分支的数量,而BrPart是不通过的条件的数量。
在此示例中,Branch具有两种模式,一种输入if语句的条件和一种不输入if语句的条件,并且出现一个BrPart模式,因为未测试没有输入if语句的条件。

添加测试源

添加一个测试以使分支100%。

py_test_main.py

1
2
3
4
5
6
7
8
9
10
import pytest
import testing_mod

def test_ok_sample():
    result = testing_mod.add_calc(1, 2)
    assert 4 == result

def test_ok_not_if_sample():
    result = testing_mod.add_calc(2, 2)
    assert 4 == result

运行

再试一次以查看

分支是否为100%。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# pytest --cov --cov-branch -v py_test_main.py

~~~~ 略 ~~~~~

py_test_main.py::test_ok_sample PASSED                             [ 50%]
py_test_main.py::test_ok_not_if_sample PASSED                      [100%]

----------- coverage: platform win32, python 3.6.5-final-0 -----------
Name              Stmts   Miss Branch BrPart  Cover
---------------------------------------------------
py_test_main.py       8      0      0      0   100%
testing_mod.py        4      0      2      0   100%
---------------------------------------------------
TOTAL                12      0      2      0   100%

====== 1 passed in 0.08s ======

查看结果,Cover为100%,BrPart为0。

结论

覆盖率是减少错误的好方法,因为它非常简单并且从机械angular考虑。
但是,有些人认为覆盖范围是绝对的,从而导致测试遗漏并不必要地增加了测试工时。例如,"条件1和以下条件2的组合很奇怪,我错过了该错误,但是覆盖范围还可以"或"通过DB连接错误1导致的异常创建过程(对于所有SQL)通过一周。 "
另一方面,它是一个非常有效的库,因为您可以找到经常被忽略的条件,例如本示例中if语句中未包含的条件。
就个人而言,我认为将其用作辅助工具会更好,该工具首先查看覆盖率,分析条件,然后考虑是否进行测试。