python coverage模块可以有条件地忽略单元测试中的行吗?

Joh*_*ann 3 python unit-testing code-coverage python-coverage

使用nosetests和coverage模块,我希望代码的覆盖率报告能够反映正在测试的版本.考虑以下代码:

import sys
if sys.version_info < (3,3):
    print('older version of python')
Run Code Online (Sandbox Code Playgroud)

当我在python版本3.5中测试时,print()显示为未经测试.我希望覆盖范围忽略该行,但仅当我使用python版本3.3+进行测试时

有没有办法# pragma: no coverprint()声明中做一些事情只是为了什么时候sys.version_info不小于(3,3)?实际上,我想做这样的事情:

import sys
if sys.version_info < (3,3):
    print('older version of python') # pragma: [py26,py27,py32] no cover
Run Code Online (Sandbox Code Playgroud)

Ned*_*der 6

另一个选择是为不同版本的Python使用不同的.coveragerc文件,并为不同版本设置exclude_lines不同的正则表达式.

我见过有些人使用不同的注释字符串,例如# no cover 3.xvs.# no cover 2.x

但请记住,您根本不必使用评论编译指示.正则表达式应用于整个行.例如,如果您对条件使用短符号,例如:

if PY2:
    blah_py2_stuff_blah()
Run Code Online (Sandbox Code Playgroud)

然后你的Python 3的.coveragerc文件可能有:

[report]
exclude_lines =
    # pragma: no cover
    if PY2:
Run Code Online (Sandbox Code Playgroud)

然后if PY2:排除这些行,而不需要您做任何额外的评论或努力.

  • 这很棒.我喜欢这意味着没有pragma源代码的混乱.我最终根据平台和python版本在``setup.py``中创建``.coveragerc``文件.像tox的魅力,甚至与不同的平台(windows/linux/mac)一样工作. (4认同)

Dir*_*ann 3

正如您在评论中所解释的那样,您担心的是,覆盖率报告只会显示行号,并且您希望避免一次又一次地重新检查这些行号。

另一方面,我不太赞成用注释来混乱代码以使一个或另一个工具满意:对我来说,所有这些都会降低可读性。因此,我想提出另一种方法,既可以避免代码混乱,又可以减轻您始终进行重新检查的负担。

其想法是创建覆盖情况的基线,您可以根据该基线比较未来的覆盖分析结果。例如,coverage.py 的覆盖率报告如下所示(引用自http://coverage.readthedocs.org/en/coverage-4.0.3/index.html):

Name                      Stmts   Miss  Cover   Missing
-------------------------------------------------------
my_program.py                20      4    80%   33-35, 39
my_other_module.py           56      6    89%   17-23
-------------------------------------------------------
TOTAL                        76     10    87%
Run Code Online (Sandbox Code Playgroud)

此输出可以用作“基线”的基础:粗略的想法(改进见下文)是,您将此输出存储为“已接受”的覆盖情况,并将其与未来的覆盖报告进行比较。不幸的是,每当行号发生变化时,您在比较报告时就会看到差异。为了避免这种情况,可以改进这个基本思想:

借助简单的脚本编写,您可以转换报表,以便显示各行的内容而不是行号。例如,基于上面的代码示例的假设报告可能如下所示:

Name                      Stmts   Miss  Cover   Missing
-------------------------------------------------------
my_program.py                20      1     5%   3
Run Code Online (Sandbox Code Playgroud)

从此报告中,您可以为 python 版本 >= 3.3 创建以下“覆盖基线”,例如在 file 中coverage-baseline-33andabove.txt

my_program.py:
-    print('older version of python')
Run Code Online (Sandbox Code Playgroud)

例如,即使您将进一步的导入行添加到文件顶部,该基线看起来也一样。将为您确定覆盖范围的其他 python 版本创建更多基线文件。

进一步可能的改进可能是将线路组分开,例如:

my_program.py:
*
-    print('older version of python')
*
-    cleanup()
-    assert False
my_program2.py:
*
-    print('older version of python')
Run Code Online (Sandbox Code Playgroud)

仅当未涵盖的代码更改(添加、删除、修改、移动)以及文件名更改时,您才会看到差异。然后,差异的发生将要求您存储新的“覆盖基线”,或者添加更多测试,直到再次达到原始基线内容。