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/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
If I run pytest
like this:
pytest -s --junitxml=pytests.xml --cov-report xml --cov-report term-missing --cov-branch --cov=ex_secure
Then the top-level package in the resulting coverage.xml
is named .
:
<package branch-rate="0.4722" complexity="0" line-rate="0.6801" name=".">
But if I call pytest
like this:
pytest -s --junitxml=pytests.xml --cov-report xml --cov-report term-missing --cov-branch --cov=ex_secure.base --cov=ex_secure.metrics --cov=ex_secure.keys
Then the top-level package is correctly named ex_secure
:
<package branch-rate="0.4722" complexity="0" line-rate="0.6801" name="ex_secure">
It's an okay workaround for now, but it's not ideal. If I add more packages, I have to keep enumerating them (or they'll be missing on the coverage report). Additionally, __init__.py
isn't covered using this mechanism.
What am I doing wrong here?
UPDATE 1:
If I run Python Coverage directly instead of using pytest-cov
, it works as expected:
coverage run --branch --source=ex_secure -m pytest -s --junitxml=pytests.xml
coverage xml
Then:
<package branch-rate="0.4722" complexity="0" line-rate="0.6771" name="ex_secure">
UPDATE 2:
If I run PyTest as I originally did, but then re-generate the XML report with Python Coverage directly, the re-generated report gets corrected, but has slightly different numbers:
pytest -s --junitxml=pytests.xml --cov-report xml --cov-report term-missing --cov-branch --cov=ex_secure
coverage xml
Then:
<package branch-rate="0.3058" complexity="0" line-rate="0.4769" name="ex_secure">
Unfortunately, this is a rather nasty two-part bug that spans both Py-Coverage and PyTest-Cov. It is described in detail on the PyTest-Cov GitHub and the Py-Coverage BitBucket.
In short, calling coverage xml
from the command line doesn't allow you to pass in sources
, so most people don't see this problem, but you can pass in sources
when using the Python API for Py-Coverage, and that API does not correctly handle the sources
attribute. PyTest-Cov, meanwhile, uses the Python API for Py-Coverage, so when you call PyTest-Cov with --cov=xxxx
and --cov-report xml
, you end up with this problem.