import importlib
import re
import sys
TEST_MODULE = re.compile(r'tests\.((?:\w.+\.)*)test_(\w+)')
FIDDLE_WITH_COVERAGE = False
def module_path(test_module):
match = TEST_MODULE.fullmatch(test_module)
if match:
yield ''.join(match.groups())
def pytest_addoption(parser):
parser.addoption('--divide-and-cover', action='store_true',
help='activate divide and cover tracing')
def pytest_configure(config):
if config.option.divide_and_cover:
from coverage_handler import UNDER_WRAPPER
if UNDER_WRAPPER:
global FIDDLE_WITH_COVERAGE
FIDDLE_WITH_COVERAGE = True
else:
print('Warning: called with --divide-and-cover, but not running '
'under divide_and_cover. Not activating plugin.')
# This is probably wrong
def pytest_collection_modifyitems(session, config, items):
if FIDDLE_WITH_COVERAGE:
from .coverage_handler import coverage_script
modules = sys.modules.copy()
paths = []
for test_path in modules:
for module_path_ in module_path(test_path):
paths.append(module_path_)
coverage_script.new_coverage(test_path, module_path_)
# This next bit needs to be run under a coverage tracer, with source
# based on paths. Specifically, it should use the root package from
# each path
roots = sorted({path.split('.', 1)[0] for path in paths})
coverage_script.make_import_coverage(roots)
print('Covering packages under: {}'.format(roots))
coverage_script.switch_coverage(coverage_script.import_coverage)
try:
for path in paths:
try:
importlib.import_module(path)
except ImportError:
print('Could not import {}'.format(path))
finally:
coverage_script.deactivate_coverage()
def pytest_runtest_setup(item):
if FIDDLE_WITH_COVERAGE:
from .coverage_handler import coverage_script
coverage_script.activate_coverage(item.obj.__module__)
def pytest_runtest_teardown(item, nextitem):
if FIDDLE_WITH_COVERAGE:
from .coverage_handler import coverage_script
coverage_script.deactivate_coverage()
Comments