pytest-cov: Using pytest-cov for coverage results in top-level package name of "." when using coverage.py doesn't
First, versions:
$ python --version
Python 2.7.11
$ pip freeze|grep coverage
coverage==4.4.1
$ pip freeze|grep pytest-cov
pytest-cov==2.5.1
Happens on Ubuntu 12.04, Ubuntu 16.04, and Mac OS X El Capitan 10.11.6. Can’t test anything else, but seems safe to say it would be the same.
I have a project laid out like this:
proj/ex_secure/__init__.py
proj/ex_secure/base.py
proj/ex_secure/metrics.py
proj/ex_secure/keys.py
proj/ex_secure/utils.py
proj/tests/test_base.py
proj/tests/test_metrics.py
proj/tests/test_keys.py
proj/.gitignore
proj/.pep8
proj/README.rst
proj/setup.cfg
proj/setup.py
All the example commands below I run from within the proj
directory.
First, I run coverage
directly:
$ coverage run --branch --source=ex_secure -m pytest -s --junitxml=pytests.xml
... output that doesn't matter ...
$ coverage xml
$ coverage report
Name Stmts Miss Branch BrPart Cover
-------------------------------------------------------------------
ex_secure/__init__.py 1 0 0 0 100%
ex_secure/base.py 274 55 74 12 74%
ex_secure/keys.py 31 6 6 0 78%
ex_secure/metrics.py 10 2 4 0 57%
ex_secure/util.py 238 238 98 0 0%
And the top package of the XML file looks like so:
<package branch-rate="0.3058" complexity="0" line-rate="0.4769" name="ex_secure">
Next, I run pytest
with the pytest-cov
plugin:
$ pytest -s --junitxml=pytests.xml --cov-report xml --cov-report term --cov-branch --cov=ex_secure
... output that doesn't matter ...
---------- coverage: platform darwin, python 2.7.11-final-0 ----------
Name Stmts Miss Branch BrPart Cover
-------------------------------------------------------------------
ex_secure/__init__.py 1 0 0 0 100%
ex_secure/base.py 274 55 74 12 74%
ex_secure/keys.py 31 6 6 0 78%
ex_secure/metrics.py 10 2 4 0 57%
ex_secure/util.py 238 238 98 0 0%
And the top package of the XML file looks like so:
<package branch-rate="0.3058" complexity="0" line-rate="0.4769" name=".">
Notice the name
of the package is now .
instead of ex_secure
. However, if I then run coverage xml
to re-generate the report:
$ coverage xml
The XML file looks right again:
<package branch-rate="0.3058" complexity="0" line-rate="0.4769" name="ex_secure">
So I tried running pytest
a different way:
$ pytest -s --junitxml=pytests.xml --cov-report xml --cov-report term --cov-branch --cov=ex_secure.base --cov=ex_secure.keys --cov=ex_secure.metrics --cov=ex_secure.util
... output that doesn't matter ...
---------- coverage: platform darwin, python 2.7.11-final-0 ----------
Name Stmts Miss Branch BrPart Cover
-------------------------------------------------------------------
ex_secure/base.py 274 55 74 12 74%
ex_secure/keys.py 31 6 6 0 78%
ex_secure/metrics.py 10 2 4 0 57%
Now the XML also looks right:
<package branch-rate="0.4722" complexity="0" line-rate="0.6766" name="ex_secure">
But this has several downsides:
- I have to enumerate everything, and I miss coverage info for new files added if they are not enumerated.
- Can’t cover
__init__.py
utils.py
is not in the report anymore because none of its lines are covered, resulting in incorrectly high coverage results- Branch rate and line rate are now different (because of missing
__init__.py
andutils.py
About this issue
- Original URL
- State: open
- Created 7 years ago
- Reactions: 11
- Comments: 21 (4 by maintainers)
Just to add, I’m having the same problem. We have a slightly weird package layout, with a main package and an extra module in the same level, and pytest-cov does the same
name='.'
thing, which breaks our Sonar integration.I did some debugging and I might have an answer:
This is the XML report generation using
pytest-cov
:This is the XML report generation using
coverage xml
immediately after runningpytest
withpytest-cov
:Upon further examination of the code,
coverage xml
does not allow the--sources
argument and has no way to passsources
intoxml_report
. That’s why it works. On the other hand,pytest-cov
is creating a singleCoverage
object and setting itssources
, which get passed on to thexml_report
, and so it strips that from all the file names before figuring out their package names.So one could argue Coverage should be a little smarter here, but also
pytest-cov
is not callingxml_report
the same way thatcoverage xml
would, and that seems like a legit bug inpytest-cov
to me.Can confirm I encounter exactly the problem described by https://github.com/pytest-dev/pytest-cov/issues/175#issue-269116254 and https://github.com/pytest-dev/pytest-cov/issues/175#issuecomment-354476616
the reasong https://github.com/pytest-dev/pytest-cov/issues/175#issuecomment-358335476 doesn’t work for me is that I have two sub-packages in one repository, so I need pytest-cov to actually generate the coverage report correctly
Yep, that’s correct. You would include /foo/ and /bob/ under the include section of [report] in your coveragerc. When you tell pytest-cov to cover “.”, coverage will check that file and only report on foo and bob.