I have a python project where I use:
and many more.
Basically, I want to add tox
to my gitlab pipelines. And almost everything seems to work, calling mypy
, flake8
or black
from tox works fine. But when I call tox -e py37
(so I want to run the tests) with coverage enabled, the tests are run, I can see their results, but the coverage is 0%
(100%
only on empty __init__
files etc.) and I get the warning: Coverage.py warning: No data was collected. (no-data-collected)
.
This is my pytest-relevant part of tox.ini
:
[tox]
envlist = flake8,mypy,black,py37
[testenv]
extras = tests
commands=
pytest --cov -ra --tb=short {posargs}
And this is my .coveragerc
:
[run]
branch = True
source =
foo
omit =
foo/__init__.py
foo/__main__.py
foo/bar/__init__.py
foo/baz/__init__.py
[report]
exclude_lines =
pragma: no cover
if __name__ == .__main__.
show_missing = True
I have a working setup.py
which includes all needed packages: pytest
, pytest-cov
and many more for style etc. (which works). I also have __init__.py
in my tests
folder.
Funny thing is, if I call the same command I have in tox.ini
from my command line (in pipenv
): pytest --cov -ra --tb=short
, I get the same results but with normal coverage (in my case it's 100%
).
Is there a way to fix it? I don't want my pipelines to show wrong coverage + even if they somehow magically would actually get the right one, I still would want to see it locally.
P.S When I was trying to resolve the issue I called tox with tox --sitepackages -e py37
and I got some errors like test command found but not in testenv
. And besides those errors, my coverage was fine then. But then I uninstalled tox
, pytest
and pytest-cov
from my global pip register and now with or without --sitepackages
flag I still get 0%
coverage
The root-cause is that pytest
during runnung tox
uses the installed sources (under site-packages) while the coverage reporter count the hits files in the working directory (ie. your local git repo).
Solution
Add the tox's virtual-env path to coverage:
[testenv]
pytest --cov={envsitepackagesdir}/foo
For more detail read substitutions for virtualenv-related sections
Work-around
Set PYTHONPATH
to working directory (ie. export PYTHONPATH=.
). Note, that you need to pass the PYTHONPATH
to tox
by:
[testenv]
passenv =
PYTHONPATH
This is easy, but using this way, you don't test the installation, because the tests runs on the files in the working directory.
Have usedevelop=True
in the tox.ini:
[testenv]
usedevelop=True
pytest --cov=foo
which results in the same behavior as @zvi-baratz's solution but is less hacky.
The only caveat here is that if the package has a custom install_command
this solution can not be used. Please see the docs for more info.
If that is the case, you can use --cov={envsitepackagesdir}/foo
as a
work-around.
envsitepackagesdir
all the time?Because it results in the coverage report having lengthier paths that point to files in the python environment created by tox instead of the actual project path.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With