|
4 | 4 | import warnings
|
5 | 5 |
|
6 | 6 | import pytest
|
| 7 | +import coverage |
7 | 8 | from coverage.misc import CoverageException
|
8 | 9 |
|
9 | 10 | from . import compat
|
@@ -48,6 +49,16 @@ def validate_fail_under(num_str):
|
48 | 49 | return float(num_str)
|
49 | 50 |
|
50 | 51 |
|
| 52 | +def validate_contexts(arg): |
| 53 | + if coverage.version_info <= (5, 0): |
| 54 | + msg = 'Contexts are only supported with coverage.py >= 5.x' |
| 55 | + raise argparse.ArgumentTypeError(msg) |
| 56 | + if arg != "test": |
| 57 | + msg = '--cov-contexts=test is the only supported value' |
| 58 | + raise argparse.ArgumentTypeError(msg) |
| 59 | + return arg |
| 60 | + |
| 61 | + |
51 | 62 | class StoreReport(argparse.Action):
|
52 | 63 | def __call__(self, parser, namespace, values, option_string=None):
|
53 | 64 | report_type, file = values
|
@@ -88,6 +99,9 @@ def pytest_addoption(parser):
|
88 | 99 | 'Default: False')
|
89 | 100 | group.addoption('--cov-branch', action='store_true', default=None,
|
90 | 101 | help='Enable branch coverage.')
|
| 102 | + group.addoption('--cov-contexts', action='store', metavar='CONTEXT', |
| 103 | + type=validate_contexts, |
| 104 | + help='Dynamic contexts to use. "test" for now.') |
91 | 105 |
|
92 | 106 |
|
93 | 107 | def _prepare_cov_source(cov_source):
|
@@ -151,6 +165,9 @@ def __init__(self, options, pluginmanager, start=True):
|
151 | 165 | elif start:
|
152 | 166 | self.start(engine.Central)
|
153 | 167 |
|
| 168 | + if getattr(options, 'cov_contexts', None) == 'test': |
| 169 | + pluginmanager.register(TestContextPlugin(self.cov_controller.cov), '_cov_contexts') |
| 170 | + |
154 | 171 | # worker is started in pytest hook
|
155 | 172 |
|
156 | 173 | def start(self, controller_cls, config=None, nodeid=None):
|
@@ -308,6 +325,24 @@ def pytest_runtest_call(self, item):
|
308 | 325 | yield
|
309 | 326 |
|
310 | 327 |
|
| 328 | +class TestContextPlugin(object): |
| 329 | + def __init__(self, cov): |
| 330 | + self.cov = cov |
| 331 | + |
| 332 | + def pytest_runtest_setup(self, item): |
| 333 | + self.switch_context(item, 'setup') |
| 334 | + |
| 335 | + def pytest_runtest_teardown(self, item): |
| 336 | + self.switch_context(item, 'teardown') |
| 337 | + |
| 338 | + def pytest_runtest_call(self, item): |
| 339 | + self.switch_context(item, 'run') |
| 340 | + |
| 341 | + def switch_context(self, item, when): |
| 342 | + context = "{item.nodeid}|{when}".format(item=item, when=when) |
| 343 | + self.cov.switch_context(context) |
| 344 | + |
| 345 | + |
311 | 346 | @pytest.fixture
|
312 | 347 | def no_cover():
|
313 | 348 | """A pytest fixture to disable coverage."""
|
|
0 commit comments