45

对于Jedi,我们想要生成我们的测试覆盖率。stackoverflow 中有一个相关的问题,但没有帮助。

我们使用 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 中修复它。它是公开的。

4

5 回答 5

77

@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它可以加快您的覆盖率报告。

于 2013-05-13T14:23:27.667 回答
9

我通过这个简化导入依赖的补丁和命令将测试覆盖率固定为 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 插件忽略与此文件一起导入的所有内容,则它可以正常工作,尽管这很痛苦。__init__.py我也将其排除settings.py在报告之外,因为它们很简单并且覆盖范围很广,但是它们也会在 conftest 的依赖中过早导入。

于 2013-05-12T23:26:23.333 回答
6

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

解决方法是:

$ export PYTHONPATH="."

结果正确后。

我在过去的几个py.test命令中遇到了导入某些东西的问题,而设置PYTHONPATHenv 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工具的建议。

于 2016-01-20T15:04:37.427 回答
3

我在 py.test、覆盖率和 django 插件方面遇到了这个问题。显然,模型文件是在开始覆盖之前导入的。甚至没有用于早期加载覆盖插件的“-p覆盖”。

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

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

def test_my_model():
  ...
于 2013-08-07T13:21:23.847 回答
0

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

pytest --cov=src --cov-report=html
于 2020-04-29T07:33:27.137 回答