summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--coverage/misc.py11
-rw-r--r--pylintrc1
-rw-r--r--tests/coveragetest.py30
-rw-r--r--tests/test_api.py4
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
diff --git a/pylintrc b/pylintrc
index c9f1dc3d..cad40e8d 100644
--- a/pylintrc
+++ b/pylintrc
@@ -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):