pytest-cov
                                
                                 pytest-cov copied to clipboard
                                
                                    pytest-cov copied to clipboard
                            
                            
                            
                        Set `cov_source` dynamically
Summary
I am currently working on the integration of pytest-cov into a custom pytest plugin. As I want to find files with no coverage as well, I am trying to set cov_source automatically inside my plugin, where I already have a list of all relevant paths.
Is there a way to actually set cov_source dynamically?
Expected vs actual result
Using pytest --cov path/to/my/package --cov-report html will report uncovered files, which is correct.
Trying to set cov_source dynamically from within Python code and running pytest --cov --cov-report html will not report the uncovered files.
Reproducer
Code inside my custom plugin, which is being executed, but has no effect (based upon https://github.com/pytest-dev/pytest-cov/issues/418#issuecomment-657219659):
def pytest_configure(config):
    coverage_plugin = config.pluginmanager.get_plugin('_cov')
    if not coverage_plugin:
        # Coverage is not requested.
        return
    if coverage_plugin.options.no_cov:
        # Coverage has been disabled explicitly.
        return
    if not coverage_plugin.options.cov_source:
        # No coverage parameters passed by user, which means we can inject our own.
        coverage_plugin.options.cov_source = get_directories_for_coverage()
Versions
- Python 3.6.15
- pytest 5.4.0
- pytest-cov 2.1.1
- coverage 5.3.1
Config
pytest.ini:
[pytest]
python_files=
 */tests/*
python_functions=test*
norecursedirs=
 lib
 lib64
addopts = --disable-warnings
.coveragerc:
[run]
branch = True
omit = 
 */tests/*
 */migrations/*
 bin/*
 lib/*
 lib64/*
[html]
directory = htmlcov
What has been tried to solve the problem
I looked through the source code to find possible alternatives for injecting my code, like using
coverage_plugin.cov_controller.cov.config.source = coverage_plugin.options.cov_source
coverage_plugin.cov_controller.combining_cov.config.source = coverage_plugin.options.cov_source
or adding parameters in pytest_cmdline_main.
Due to pytest_load_initial_conftests inside pytest_cov.plugin where pytest_cov.CovPlugin is initialized and pytest_cov.CovPlugin.__init__ calling pytest_cov.CovPlugin.start, which populates the cov_controller, the modifications I tried seem to fail/seem to have no effect.
The only way I could get this to work is by explicitly "restarting" the plugin after setting the cov_source option:
coverage_plugin.options.cov_source = get_directories_for_coverage()
coverage_plugin.start(controller_cls=coverage_plugin.cov_controller.__class__)
But this approach feels rather hackish and I would prefer a clean solution, as it will show imports etc. as uncovered, which is wrong as well.