将py.test与coverage一起使用不包括导入

时间:2013-05-06 18:17:54

标签: python pytest coverage.py

对于Jedi,我们要生成test coverage。 stackoverflow中有related question,但它没有用。

我们使用py.test作为测试运行器。但是,我们无法将导入和其他“导入”内容添加到报表中。例如,__init__.py始终报告为未被发现:

Name                           Stmts   Miss  Cover
--------------------------------------------------
jedi/__init__                      5      5     0%
[..]

显然,此文件正在导入,因此应报告为已测试。

我们开始这样的测试[*]:

py.test --cov jedi

正如您所看到的,我们正在使用pytest-coverage

那么如何才能正确计算__init__.py等文件的覆盖范围?

[*]我们还尝试在没有--doctest-modules的情况下启动测试(从pytest.ini中删除)并在py.test -p pytest_cov --cov jedi之前激活覆盖模块。他们都没有工作。

我提供了赏金。请尝试在Jedi内修复它。它是公开的。

5 个答案:

答案 0 :(得分:61)

@hynekcer给了我正确的想法。但基本上最简单的解决方案就在其他地方:

摆脱pytest-cov

使用

coverage run --source jedi -m py.test
coverage report

代替!!!这样你就可以在你当前的py.test配置上运行一个覆盖,这完全没问题!从哲学上讲,这也是正确的方法:让每个程序做好一件事 - py.test运行测试,coverage检查代码覆盖率。

现在这可能听起来像个咆哮,但真的。 pytest-cov暂时没有正常工作。有些测试失败了,只是因为我们使用过它。


截至 2014 ,pytest-cov似乎易手。 py.test --cov jedi test似乎再次成为一个有用的命令(查看注释)。但是,您不需要使用它。但与xdist结合使用可以加快您的报道速度。

答案 1 :(得分:8)

我通过this patch将测试覆盖率修复为94%,这简化了导入依赖关系并通过以下命令:

py.test --cov jedi test                    # or
py.test --cov jedi test --cov-report=html  # + a listing with red uncovered lines

未覆盖的行仅在条件命令或一些较少使用的函数中,但所有标题都被完全覆盖。

问题是测试配置test/conftest.py确实过早地依赖于项目中的所有文件的依赖项。 conftest文件还定义了在运行测试之前应设置的其他命令行选项和设置。因此,我认为如果pytest_cov插件忽略了与此文件一起导入的所有内容,那么pytest_cov插件可以正常工作,尽管这很痛苦。我还从报告中排除了__init__.pysettings.py,因为它们很简单并具有完整的覆盖范围,但它们也会在conftest的依赖项中过早导入。

答案 2 :(得分:4)

就我而言,所有测试都在运行,但覆盖率为0%。

修复是:

$ export PYTHONPATH="."

结果正确后。

我在py.test命令的过去几个问题中导入了一些问题并设置PYTHONPATH env var是解决方案。这次它对我有用。

awslogs

的真实例子

首先PYTHONPATH取消设置:

$ py.test --cov=awslogs  tests/
========================================= test session starts =========================================
platform linux2 -- Python 2.7.9, pytest-2.8.5, py-1.4.31, pluggy-0.3.1
rootdir: /home/javl/sandbox/awslogs/github/awslogs, inifile:
plugins: cov-2.2.0
collected 11 items

tests/test_it.py ...........Coverage.py warning: No data was collected.

--------------------------- coverage: platform linux2, python 2.7.9-final-0 ---------------------------
Name                    Stmts   Miss  Cover
-------------------------------------------
awslogs/__init__.py         2      2     0%
awslogs/bin.py             85     85     0%
awslogs/core.py           143    143     0%
awslogs/exceptions.py      12     12     0%
-------------------------------------------
TOTAL                     242    242     0%

====================================== 11 passed in 0.38 seconds ======================================

结果覆盖率为0%。

然后我设置PYTHONPATH

$ export PYTHONPATH="."

重新运行测试:

$ py.test --cov=awslogs  tests/
========================================= test session starts =========================================
platform linux2 -- Python 2.7.9, pytest-2.8.5, py-1.4.31, pluggy-0.3.1
rootdir: /home/javl/sandbox/awslogs/github/awslogs, inifile:
plugins: cov-2.2.0
collected 11 items

tests/test_it.py ...........
--------------------------- coverage: platform linux2, python 2.7.9-final-0 ---------------------------
Name                    Stmts   Miss  Cover
-------------------------------------------
awslogs/__init__.py         2      0   100%
awslogs/bin.py             85      9    89%
awslogs/core.py           143     12    92%
awslogs/exceptions.py      12      2    83%
-------------------------------------------
TOTAL                     242     23    90%

====================================== 11 passed in 0.44 seconds ======================================

现在覆盖率为90%。

警告:操纵PYTHONPATH会产生奇怪的副作用。目前我遇到问题,基于pbr的包在构建可分发时创建egg目录,如果PYTHONPATH设置为“。”,它会自动将egg相关包视为已安装。出于这个原因,我停止使用pytest-cov并按照建议使用coverage工具。

答案 3 :(得分:2)

我在py.test,coverage和django插件中遇到了这个问题。 显然,模型文件是在启动coverage之前导入的。 早期加载coverage-plugin的“-p覆盖率”甚至都没有。

我通过从sys.modules中删除models模块并在测试模型的测试文件中重新导入它来修复它(丑陋?):

import sys
del sys.modules['project.my_app.models']
from project.my_app import models

def test_my_model():
  ...

答案 4 :(得分:0)

如果您使用烧瓶,那么这将帮助您解决问题-

pytest --cov=src --cov-report=html