Python 使用覆盖范围的 py.test 不包括导入
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16404716/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using py.test with coverage doesn't include imports
提问by Dave Halter
For Jediwe want to generate our test coverage. There is a related questionin stackoverflow, but it didn't help.
对于Jedi,我们希望生成我们的测试覆盖率。stackoverflow 中有一个相关的问题,但没有帮助。
We're using py.test as a test runner. However, we are unable to add the imports and other "imported" stuff to the report. For example __init__.pyis always reported as being uncovered:
我们使用 py.test 作为测试运行器。但是,我们无法将导入和其他“导入”的内容添加到报告中。例如__init__.py,总是报告为未发现:
Name Stmts Miss Cover
--------------------------------------------------
jedi/__init__ 5 5 0%
[..]
Clearly this file is being imported and should therefore be reported as tested.
很明显,这个文件正在被导入,因此应该报告为已测试。
We start tests like this [*]:
我们开始这样的测试 [*]:
py.test --cov jedi
As you can see we're using pytest-coverage.
如您所见,我们正在使用pytest-coverage.
So how is it possible to properly count coverage of files like __init__.py?
那么如何正确计算文件的覆盖范围__init__.py呢?
[*] We also tried starting test without --doctest-modules(removed from pytest.ini) and activate the coverage module earlier by py.test -p pytest_cov --cov jedi. Neither of them work.
[*] 我们还尝试在没有--doctest-modules(从 中删除pytest.ini)的情况下开始测试并通过 提前激活覆盖模块py.test -p pytest_cov --cov jedi。它们都不起作用。
I've offered a bounty. Please try to fix it within Jedi. It's publicly available.
我提供了赏金。请尝试在绝地中修复它。它是公开的。
采纳答案by Dave Halter
@hynekcer gave me the right idea. But basically the easiest solution lies somewhere else:
@hynekcer 给了我正确的想法。但基本上最简单的解决方案在于其他地方:
Get rid of pytest-cov!
摆脱pytest-cov!
Use
用
coverage run --source jedi -m py.test
coverage report
instead!!! This way you're just running a coverage on your current py.test configuration, which works perfectly fine! It's also philosophically the right way to go: Make each program do one thing well - py.testruns tests and coveragechecks the code coverage.
反而!!!通过这种方式,您只是在当前的 py.test 配置上运行覆盖,这非常好!从哲学上讲,这也是正确的方法:让每个程序做好一件事——py.test运行测试并coverage检查代码覆盖率。
Now this might sound like a rant, but really. pytest-covhasn't been working properly for a while now. Some tests were failing, just because we used it.
现在这听起来像是在咆哮,但确实如此。pytest-cov有一段时间不能正常工作了。一些测试失败了,只是因为我们使用了它。
As of 2014, pytest-cov seems to have changed hands. py.test --cov jedi testseems to be a useful command again (look at the comments). However, you don't need to use it. But in combination with xdistit can speed up your coverage reports.
截至2014 年, pytest-cov 似乎已经易手。py.test --cov jedi test似乎又是一个有用的命令(看看评论)。但是,您不需要使用它。但结合xdist它可以加快您的覆盖率报告。
回答by hynekcer
I fixed the test coverage to 94%by this patchthat simplifies import dependencies and by the command:
我通过这个简化导入依赖项的补丁和命令将测试覆盖率固定为 94%:
py.test --cov jedi test # or
py.test --cov jedi test --cov-report=html # + a listing with red uncovered lines
Uncovered lines are only in conditional commands or in some less used functions but all headers are completely covered.
未覆盖的行仅在条件命令或一些较少使用的函数中,但所有标题都被完全覆盖。
The problem was that the tests configuration test/conftest.pydid import prematurely by dependencies almost all files in the project. The conftest file defines also additional command line options and settings that should be set before running the test. Therefore I think that pytest_cov plugin works correctly if it ignores everything that was imported together with this file, although it is a pain. I excluded also __init__.pyand settings.pyfrom the report because they are simple and with the complete coverage but they are also imported prematurely in the dependency of conftest.
问题是测试配置test/conftest.py确实通过依赖项过早地导入了项目中的几乎所有文件。conftest 文件还定义了在运行测试之前应该设置的其他命令行选项和设置。因此,我认为 pytest_cov 插件可以正常工作,如果它忽略与此文件一起导入的所有内容,尽管它很痛苦。我也从报告中排除了__init__.py和settings.py,因为它们很简单并且具有完整的覆盖范围,但是它们也因 conftest 的依赖而过早导入。
回答by Fabian Kreutz
I had this problem with py.test, the coverage and the django plugin. Apparently the model files are imported before coverage is started. Not even "-p coverage" for early-loading of the coverage-plugin worked.
我在 py.test、coverage 和 django 插件方面遇到了这个问题。显然,模型文件是在覆盖开始之前导入的。甚至用于早期加载覆盖插件的“-p 覆盖”都不起作用。
I fixed it (ugly?) by removing the models module from sys.modules and re-importing it in the test file that tests the model:
我通过从 sys.modules 中删除模型模块并在测试模型的测试文件中重新导入它来修复它(丑陋?):
import sys
del sys.modules['project.my_app.models']
from project.my_app import models
def test_my_model():
...
回答by Jan Vlcinsky
In my case, all the tests run, but coverage was 0%.
就我而言,所有测试都运行,但覆盖率为 0%。
The fix was:
修复是:
$ export PYTHONPATH="."
After the results were correct.
结果正确后。
I had in past few problems with py.testcommand having problems to import something and setting the PYTHONPATHenv var was the solution. It worked for me this time too.
我在过去遇到了一些问题,py.test命令在导入某些内容时遇到问题,而设置PYTHONPATHenv var 是解决方案。这次也对我有用。
My real example with awslogs
我的真实例子 awslogs
First with PYTHONPATHunset:
首先是未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 ======================================
Resulting coverage is 0%.
结果覆盖率为 0%。
Then I set the PYTHONPATH:
然后我设置了PYTHONPATH:
$ export PYTHONPATH="."
and rerun the test:
并重新运行测试:
$ 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 ======================================
Now is the coverage 90%.
现在是覆盖率90%。
WARNING: Manipulating PYTHONPATHcan have strange side effects. Currently I run into problem, that pbrbased package is creating egg directory when building distributable and if PYTHONPATHis set to ".", it automatically considers the egg related package as installed. For this reason I stopped using pytest-covand follow the advice to use coveragetool instead.
警告:操作PYTHONPATH可能会产生奇怪的副作用。目前我遇到了问题,该pbr基于软件包在构建可分发文件时正在创建 egg 目录,如果PYTHONPATH设置为“.”,它会自动将与 egg 相关的软件包视为已安装。出于这个原因,我停止使用pytest-cov并按照建议使用coverage工具。
回答by Sachin
if you are using flask then this will help you to resolve the issue-
如果您使用的是烧瓶,那么这将帮助您解决问题-
pytest --cov=src --cov-report=html

