使用setuptools调用时,Coverage.py会给出错误的统计信息

时间:2017-04-01 12:16:41

标签: python setuptools coverage.py

设置

Pytest和覆盖设置

在我的python项目myproject中,我使用以下setup.cfg

...
[aliases]
test = pytest

[tool:pytest]
addopts = --durations=5 --cov
testpaths = tests

[coverage:run]
branch = True
source = myproject
...

如您所见,我使用pytest并将其别名为test,因此我可以通过setuptools(python setup.py test)调用它。

目录布局

我的项目结构如下所示:

.
├── MANIFEST.in
├── README.rst
├── tests
│   └── test_version.py
└── myproject
    ├── __init__.py
    └── _version.py

请注意,没有.coveragerc个文件,因此所有设置都来自setup.py

问题

当我直接运行pytest时,报道给了我正确的统计数据:

running pytest
running egg_info
writing requirements to myproject.egg-info/requires.txt
writing myproject.egg-info/PKG-INFO
writing top-level names to myproject.egg-info/top_level.txt
writing dependency_links to myproject.egg-info/dependency_links.txt
writing entry points to myproject.egg-info/entry_points.txt
reading manifest file 'myproject.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
warning: no previously-included files matching '*.pyo' found under directory 'tests'
writing manifest file 'myproject.egg-info/SOURCES.txt'
running build_ext
================================================================================ test session starts ================================================================================
platform darwin -- Python 2.7.13, pytest-3.0.7, py-1.4.33, pluggy-0.4.0 -- /Users/someuser/.virtualenvs/myproject/bin/python
cachedir: .cache
rootdir: /Users/someuser/Desktop/myproject, inifile: setup.cfg
plugins: cov-2.4.0
collected 7 items 

tests/test_version.py::test_versionInfoIsExposed PASSED
tests/test_version.py::test_versionInfoIsASemanticVersionTuple PASSED
tests/test_version.py::test_versionIsExposed PASSED
tests/test_version.py::test_versionIsASemanticVersionString PASSED
tests/test_version.py::test_versionLooksGeneratedFromVersionInfo PASSED

---------- coverage: platform darwin, python 2.7.13-final-0 ----------
Name                            Stmts   Miss Branch BrPart  Cover
-----------------------------------------------------------------
myproject/__init__.py               1      0      0      0   100%
myproject/_version.py               3      0      0      0   100%
-----------------------------------------------------------------
TOTAL                               4      0      0      0   100%
...

当我运行python setup test时,报道给了我不同的(和错误的)统计数据:

running pytest
running egg_info
writing requirements to myproject.egg-info/requires.txt
writing myproject.egg-info/PKG-INFO
writing top-level names to myproject.egg-info/top_level.txt
writing dependency_links to myproject.egg-info/dependency_links.txt
writing entry points to myproject.egg-info/entry_points.txt
reading manifest file 'myproject.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
warning: no previously-included files matching '*.pyo' found under directory 'tests'
writing manifest file 'myproject.egg-info/SOURCES.txt'
running build_ext
================================================================================ test session starts ================================================================================
platform darwin -- Python 2.7.13, pytest-3.0.7, py-1.4.33, pluggy-0.4.0 -- /Users/someuser/.virtualenvs/myproject/bin/python
cachedir: .cache
rootdir: /Users/someuser/Desktop/myproject, inifile: setup.cfg
plugins: cov-2.4.0
collected 7 items 

tests/test_version.py::test_versionInfoIsExposed PASSED
tests/test_version.py::test_versionInfoIsASemanticVersionTuple PASSED
tests/test_version.py::test_versionIsExposed PASSED
tests/test_version.py::test_versionIsASemanticVersionString PASSED
tests/test_version.py::test_versionLooksGeneratedFromVersionInfo PASSED

---------- coverage: platform darwin, python 2.7.13-final-0 ----------
Name                            Stmts   Miss Branch BrPart  Cover
-----------------------------------------------------------------
myproject/__init__.py               1      1      0      0     0%
myproject/_version.py               3      3      0      0     0%
-----------------------------------------------------------------
TOTAL                               4      4      0      0     0%
...

有谁知道为什么会这样?

1 个答案:

答案 0 :(得分:1)

如果有人偶然发现了这个问题,我终于找到了解决办法。 在我的setup.cfg中,我在metadata部分中有以下行:

[metadata]
...
version = attr: myproject._version.__version__
...

这导致模块myproject.__init__myproject._version.py中的所有行在测试运行之前运行,因此coverage没有机会告诉,这些行实际上是由测试

要解决该问题,我只需阅读__version__内的setup.py信息,而无需导入模块:

# inside setup.py
_locals = {}
with open('sirup/_version.py') as fp:
    exec(fp.read(), None, _locals)
version = _locals['__version__']

setup(version=version)