pytest-cov icon indicating copy to clipboard operation
pytest-cov copied to clipboard

How to programmatically disable coverage?

Open jaraco opened this issue 5 years ago • 4 comments

I'd like to be able to programmatically disable coverage tests based on some runtime condition. In particular, on Setuptools, when running tests against PyPy, enabling coverage is prohibitively expensive (~3x run time). I'd like to be able to enable coverage tests by default, but when PyPy is detected (probably in conftest.py), disable the coverage.

I'd like to enable coverage by default by setting [pytest] addopts=--cov, but have that not take effect when running on PyPy. I've tried using tox functionality to secondarily disable by passing --no-cov, but even tox can't detect when PyPy is running; it can only detect when an environment named pypy or pypy3 is indicated, but sometimes, tox is invoked from within PyPy, so the env name is py or python, but the interpreter is still PyPy.

Is there a way within conftest to disable the coverage behavior based on arbitrary Python logic? What incantations would be necessary at what hook point to disable coverage? Thanks!

jaraco avatar Jul 02 '20 21:07 jaraco

See if https://github.com/pytest-dev/pytest-cov/issues/241#issuecomment-535522175 still works.

I guess there should be at least something documented about this.

ionelmc avatar Jul 03 '20 00:07 ionelmc

That technique does not seem to be having the desired effect. See the referenced PR on Setuptools, where the PyPy tests take ~17 minutes to run, whereas with coverage disabled, they take ~6 minutes to run.

jaraco avatar Jul 03 '20 07:07 jaraco

Ok so I have to think a bit how to give a nice api for this, but meanwhile try this:

def pytest_configure(config):
    cov = config.pluginmanager.get_plugin('_cov')
    cov.options.no_cov = True

If stuff is still slow try to add this:

    if cov.cov_controller:
        cov.cov_controller.pause()

ionelmc avatar Jul 12 '20 13:07 ionelmc

In pypa/setuptools#2254, I learned that cov.cov_controller.pause() was necessary, but it's working now! Thank you so much.

jaraco avatar Jul 12 '20 16:07 jaraco