"Python覆盖模块能否在单元测试中有条件地忽略行数?"

2024-04-29 03:46:46 发布

您现在位置:Python中文网/ 问答频道 /正文

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

import sys
if sys.version_info < (3,3):
    print('older version of python')

在pythonversion3.5中测试时,print()显示为未测试。我希望覆盖率忽略这一行,但仅当我使用python3.3+进行测试时

有没有一种方法只在sys.version_info不小于(3,3)时,对print()语句执行类似# pragma: no cover的操作吗?实际上,我想这样做:

^{pr2}$

Tags: 模块of代码import版本infoifversion
2条回答

正如您在评论中所解释的,您担心的是,覆盖率报告将只显示行号,并且您希望避免反复检查这些行号。在

另一方面,我不太赞成用注释把代码弄得乱七八糟,以使某个或另一个工具满意:对我来说,这一切都是降低可读性的。因此,我想提出另一种方法,既避免了代码的混乱,又减轻了您一直重新检查代码的负担。在

我们的想法是,创建一个覆盖情况的基线,您可以根据它来比较未来的覆盖率分析结果。例如,来自覆盖率.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%

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

在简单脚本的帮助下,您可以转换报表,以便显示相应行的内容而不是行号。例如,基于上述代码示例的假设报告可能如下所示:

^{pr2}$

从该报告中,您可以为python versions>;=3.3创建以下“覆盖率基线”,例如在文件coverage-baseline-33andabove.txt中:

my_program.py:
-    print('older version of python')

即使您在文件顶部添加了更多的导入行,这个基线看起来还是一样的。将为确定覆盖率的其他python版本创建进一步的基线文件。在

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

my_program.py:
*
-    print('older version of python')
*
-    cleanup()
-    assert False
my_program2.py:
*
-    print('older version of python')

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

另一个选择是对不同版本的Python使用不同的.coveragerc文件,并为不同版本设置不同的exclude_linesregex。在

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

但请记住,您根本不必使用注释pragma。正则表达式应用于整行。例如,如果您在条件中使用简短的表示法,例如:

if PY2:
    blah_py2_stuff_blah()

那么Python 3的.coveragerc文件可能有:

^{pr2}$

那么if PY2:行将被排除,而无需您额外的注释或努力。在

相关问题 更多 >