diff options
-rw-r--r-- | coverage/misc.py | 11 | ||||
-rw-r--r-- | pylintrc | 1 | ||||
-rw-r--r-- | tests/coveragetest.py | 30 | ||||
-rw-r--r-- | tests/test_api.py | 4 |
4 files changed, 34 insertions, 12 deletions
diff --git a/coverage/misc.py b/coverage/misc.py index 8e14aec9..9c4843ef 100644 --- a/coverage/misc.py +++ b/coverage/misc.py @@ -13,7 +13,6 @@ import types from coverage import env from coverage.backward import to_bytes, unicode_class -from coverage.backunittest import unittest ISOLATED_MODULES = {} @@ -289,15 +288,11 @@ class ExceptionDuringRun(CoverageException): pass -# unittest.SkipTest doesn't exist in Python 2.6. We backport it with -# unittest2 in the coverage.py test suite. But for production, we don't need -# to derive from SkipTest, so if it doesn't exist, just use Exception. - -class StopEverything(BaseCoverageException, getattr(unittest, 'SkipTest', Exception)): +class StopEverything(BaseCoverageException): """An exception that means everything should stop. - This derives from SkipTest so that tests that spring this trap will be - skipped automatically, without a lot of boilerplate all over the place. + The CoverageTest class converts these to SkipTest, so that when running + tests, raising this exception will automatically skip the test. """ pass @@ -68,6 +68,7 @@ disable= no-member, using-constant-test, too-many-nested-blocks, + too-many-ancestors, # Formatting stuff superfluous-parens,bad-continuation, # I'm fine deciding my own import order, diff --git a/tests/coveragetest.py b/tests/coveragetest.py index f71fcb67..bd5cf9af 100644 --- a/tests/coveragetest.py +++ b/tests/coveragetest.py @@ -13,6 +13,7 @@ import re import shlex import shutil import sys +import types from unittest_mixins import ( EnvironmentAwareMixin, StdStreamCapturingMixin, TempDirMixin, @@ -21,11 +22,12 @@ from unittest_mixins import ( import coverage from coverage import env -from coverage.backunittest import TestCase +from coverage.backunittest import TestCase, unittest from coverage.backward import StringIO, import_local_file, string_class, shlex_quote from coverage.backward import invalidate_import_caches from coverage.cmdline import CoverageScript from coverage.debug import _TEST_NAME_FILE, DebugControl +from coverage.misc import StopEverything from tests.helpers import run_command @@ -34,12 +36,36 @@ from tests.helpers import run_command OK, ERR = 0, 1 +class SkipConvertingMetaclass(type): + """Decorate all test methods to convert StopEverything to SkipTest.""" + def __new__(mcs, name, bases, attrs): + for attr_name, attr_value in attrs.items(): + if attr_name.startswith('test_') and isinstance(attr_value, types.FunctionType): + attrs[attr_name] = mcs.convert_skip_exceptions(attr_value) + + return super(SkipConvertingMetaclass, mcs).__new__(mcs, name, bases, attrs) + + @classmethod + def convert_skip_exceptions(mcs, method): + """The decorator that wraps test methods.""" + def wrapper(*args, **kwargs): + """Run the test method, and convert StopEverything to SkipTest.""" + try: + result = method(*args, **kwargs) + except StopEverything: + raise unittest.SkipTest("StopEverything!") + return result + return wrapper + +CoverageTestMethodsMixin = SkipConvertingMetaclass('CoverageTestMethodsMixin', (), {}) + class CoverageTest( EnvironmentAwareMixin, StdStreamCapturingMixin, TempDirMixin, DelayedAssertionMixin, - TestCase + CoverageTestMethodsMixin, + TestCase, ): """A base class for coverage.py test cases.""" diff --git a/tests/test_api.py b/tests/test_api.py index 71d3fd6f..6d87fc01 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -15,7 +15,7 @@ from coverage.backward import StringIO from coverage.misc import CoverageException from coverage.report import Reporter -from tests.coveragetest import CoverageTest +from tests.coveragetest import CoverageTest, CoverageTestMethodsMixin class ApiTest(CoverageTest): @@ -385,7 +385,7 @@ class UsingModulesMixin(object): sys.path.append("../moremodules") -class OmitIncludeTestsMixin(UsingModulesMixin): +class OmitIncludeTestsMixin(UsingModulesMixin, CoverageTestMethodsMixin): """Test methods for coverage methods taking include and omit.""" def filenames_in(self, summary, filenames): |