Skip to content

Commit f749bdc

Browse files
committed
WIP
1 parent 613d0ab commit f749bdc

File tree

2 files changed

+92
-0
lines changed

2 files changed

+92
-0
lines changed

src/pytest_cov/plugin.py

+35
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import warnings
55

66
import pytest
7+
import coverage
78
from coverage.misc import CoverageException
89

910
from . import compat
@@ -48,6 +49,16 @@ def validate_fail_under(num_str):
4849
return float(num_str)
4950

5051

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+
5162
class StoreReport(argparse.Action):
5263
def __call__(self, parser, namespace, values, option_string=None):
5364
report_type, file = values
@@ -88,6 +99,9 @@ def pytest_addoption(parser):
8899
'Default: False')
89100
group.addoption('--cov-branch', action='store_true', default=None,
90101
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.')
91105

92106

93107
def _prepare_cov_source(cov_source):
@@ -151,6 +165,9 @@ def __init__(self, options, pluginmanager, start=True):
151165
elif start:
152166
self.start(engine.Central)
153167

168+
if getattr(options, 'cov_contexts', None) == 'test':
169+
pluginmanager.register(TestContextPlugin(self.cov_controller.cov), '_cov_contexts')
170+
154171
# worker is started in pytest hook
155172

156173
def start(self, controller_cls, config=None, nodeid=None):
@@ -308,6 +325,24 @@ def pytest_runtest_call(self, item):
308325
yield
309326

310327

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+
311346
@pytest.fixture
312347
def no_cover():
313348
"""A pytest fixture to disable coverage."""

tests/test_pytest_cov.py

+57
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import glob
22
import os
33
import platform
4+
import sqlite3
45
import subprocess
56
import sys
67
from itertools import chain
@@ -1928,3 +1929,59 @@ def test_cov_and_no_cov(testdir):
19281929
script)
19291930

19301931
assert result.ret == 0
1932+
1933+
1934+
CONTEXTFUL_TESTS = '''\
1935+
import unittest
1936+
1937+
def test_one():
1938+
assert 1 == 1
1939+
1940+
def test_two():
1941+
assert 2 == 2
1942+
1943+
class OldStyleTests(unittest.TestCase):
1944+
def setUp(self):
1945+
self.three = 3
1946+
def tearDown(self):
1947+
self.three = None
1948+
def test_three(self):
1949+
assert self.three == 3
1950+
'''
1951+
1952+
@pytest.mark.skipif("coverage.version_info < (5, 0)")
1953+
@xdist_params
1954+
def test_contexts(testdir, opts):
1955+
script = testdir.makepyfile(CONTEXTFUL_TESTS)
1956+
result = testdir.runpytest('-v',
1957+
'--cov=%s' % script.dirpath(),
1958+
'--cov-contexts=test',
1959+
script,
1960+
*opts.split()
1961+
)
1962+
result.stdout.fnmatch_lines([
1963+
'test_contexts* 100%*',
1964+
])
1965+
con = sqlite3.connect(".coverage")
1966+
cur = con.cursor()
1967+
contexts = set(r[0] for r in cur.execute("select context from context"))
1968+
assert contexts == {
1969+
'',
1970+
'test_contexts.py::test_two|run',
1971+
'test_contexts.py::test_one|run',
1972+
'test_contexts.py::OldStyleTests::test_three|run',
1973+
}
1974+
1975+
1976+
@pytest.mark.skipif("coverage.version_info >= (5, 0)")
1977+
def test_contexts_not_supported(testdir):
1978+
script = testdir.makepyfile(CONTEXTFUL_TESTS)
1979+
result = testdir.runpytest('-v',
1980+
'--cov=%s' % script.dirpath(),
1981+
'--cov-contexts=test',
1982+
script,
1983+
)
1984+
result.stderr.fnmatch_lines([
1985+
'*argument --cov-contexts: Contexts are only supported with coverage.py >= 5.x',
1986+
])
1987+
assert result.ret != 0

0 commit comments

Comments
 (0)