diff options
-rw-r--r-- | coverage/config.py | 2 | ||||
-rw-r--r-- | coverage/control.py | 7 | ||||
-rw-r--r-- | tests/test_api.py | 15 |
3 files changed, 23 insertions, 1 deletions
diff --git a/coverage/config.py b/coverage/config.py index 6372f4c0..452d320e 100644 --- a/coverage/config.py +++ b/coverage/config.py @@ -195,6 +195,7 @@ class CoverageConfig(object): self.run_omit = None self.source = None self.timid = False + self._crash = None # Defaults for [report] self.exclude_list = DEFAULT_EXCLUDE[:] @@ -359,6 +360,7 @@ class CoverageConfig(object): ('run_omit', 'run:omit', 'list'), ('source', 'run:source', 'list'), ('timid', 'run:timid', 'boolean'), + ('_crash', 'run:_crash'), # [report] ('exclude_list', 'report:exclude_lines', 'regexlist'), diff --git a/coverage/control.py b/coverage/control.py index fdd1556e..6e59078c 100644 --- a/coverage/control.py +++ b/coverage/control.py @@ -18,7 +18,7 @@ from coverage.collector import Collector, CTracer from coverage.config import read_coverage_config from coverage.context import should_start_context_test_function, combine_context_switchers from coverage.data import CoverageData, combine_parallel_data -from coverage.debug import DebugControl, write_formatted_info +from coverage.debug import DebugControl, short_stack, write_formatted_info from coverage.disposition import disposition_debug_msg from coverage.files import PathAliases, abs_file, relative_filename, set_relative_directory from coverage.html import HtmlReporter @@ -280,6 +280,11 @@ class Coverage(object): self._wrote_debug = True self._write_startup_debug() + # '[run] _crash' will raise an exception if the value is close by in + # the call stack, for testing error handling. + if self.config._crash and self.config._crash in short_stack(limit=4): + raise Exception("Crashing because called by {}".format(self.config._crash)) + def _write_startup_debug(self): """Write out debug info at startup if needed.""" wrote_any = False diff --git a/tests/test_api.py b/tests/test_api.py index 30a90c3c..369324f7 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -676,6 +676,21 @@ class ApiTest(CoverageTest): with self.assertRaisesRegex(CoverageException, msg): cov.switch_context("test3") + def test_config_crash(self): + # The internal '[run] _crash' setting can be used to artificially raise + # exceptions from inside Coverage. + cov = coverage.Coverage() + cov.set_option("run:_crash", "test_config_crash") + with self.assertRaisesRegex(Exception, "Crashing because called by test_config_crash"): + cov.start() + + def test_config_crash_no_crash(self): + # '[run] _crash' really checks the call stack. + cov = coverage.Coverage() + cov.set_option("run:_crash", "not_my_caller") + cov.start() + cov.stop() + class CurrentInstanceTest(CoverageTest): """Tests of Coverage.current().""" |