summaryrefslogtreecommitdiff
path: root/coverage/test_helpers.py
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2016-01-07 20:07:04 -0500
committerNed Batchelder <ned@nedbatchelder.com>2016-01-07 20:07:04 -0500
commitb7035114aa515d9d1fe171a9bf678868e76d8f74 (patch)
tree60609f38079b9de18cdbee1d255e96e9c666dd31 /coverage/test_helpers.py
parentd1c92d8e6b066a7b16d625b566853821afe8b46c (diff)
parentd93ddb9524a3e3535541812bbeade8e8ff822409 (diff)
downloadpython-coveragepy-git-b7035114aa515d9d1fe171a9bf678868e76d8f74.tar.gz
Branch analysis is now done with AST instead of bytecode
Diffstat (limited to 'coverage/test_helpers.py')
-rw-r--r--coverage/test_helpers.py65
1 files changed, 59 insertions, 6 deletions
diff --git a/coverage/test_helpers.py b/coverage/test_helpers.py
index 50cc3298..a76bed35 100644
--- a/coverage/test_helpers.py
+++ b/coverage/test_helpers.py
@@ -162,20 +162,20 @@ class StdStreamCapturingMixin(TestCase):
# nose keeps stdout from littering the screen, so we can safely Tee it,
# but it doesn't capture stderr, so we don't want to Tee stderr to the
# real stderr, since it will interfere with our nice field of dots.
- self.old_stdout = sys.stdout
+ old_stdout = sys.stdout
self.captured_stdout = StringIO()
sys.stdout = Tee(sys.stdout, self.captured_stdout)
- self.old_stderr = sys.stderr
+ old_stderr = sys.stderr
self.captured_stderr = StringIO()
sys.stderr = self.captured_stderr
- self.addCleanup(self.cleanup_std_streams)
+ self.addCleanup(self.cleanup_std_streams, old_stdout, old_stderr)
- def cleanup_std_streams(self):
+ def cleanup_std_streams(self, old_stdout, old_stderr):
"""Restore stdout and stderr."""
- sys.stdout = self.old_stdout
- sys.stderr = self.old_stderr
+ sys.stdout = old_stdout
+ sys.stderr = old_stderr
def stdout(self):
"""Return the data written to stdout during the test."""
@@ -186,6 +186,59 @@ class StdStreamCapturingMixin(TestCase):
return self.captured_stderr.getvalue()
+class DelayedAssertionMixin(TestCase):
+ """A test case mixin that provides a `delayed_assertions` context manager.
+
+ Use it like this::
+
+ with self.delayed_assertions():
+ self.assertEqual(x, y)
+ self.assertEqual(z, w)
+
+ All of the assertions will run. The failures will be displayed at the end
+ of the with-statement.
+
+ NOTE: this only works with some assertions. These are known to work:
+
+ - `assertEqual(str, str)`
+
+ - `assertMultilineEqual(str, str)`
+
+ """
+ def __init__(self, *args, **kwargs):
+ super(DelayedAssertionMixin, self).__init__(*args, **kwargs)
+ # This mixin only works with assert methods that call `self.fail`. In
+ # Python 2.7, `assertEqual` didn't, but we can do what Python 3 does,
+ # and use `assertMultiLineEqual` for comparing strings.
+ self.addTypeEqualityFunc(str, 'assertMultiLineEqual')
+ self._delayed_assertions = None
+
+ @contextlib.contextmanager
+ def delayed_assertions(self):
+ """The context manager: assert that we didn't collect any assertions."""
+ self._delayed_assertions = []
+ old_fail = self.fail
+ self.fail = self._delayed_fail
+ try:
+ yield
+ finally:
+ self.fail = old_fail
+ if self._delayed_assertions:
+ if len(self._delayed_assertions) == 1:
+ self.fail(self._delayed_assertions[0])
+ else:
+ self.fail(
+ "{0} failed assertions:\n{1}".format(
+ len(self._delayed_assertions),
+ "\n".join(self._delayed_assertions),
+ )
+ )
+
+ def _delayed_fail(self, msg=None):
+ """The stand-in for TestCase.fail during delayed_assertions."""
+ self._delayed_assertions.append(msg)
+
+
class TempDirMixin(SysPathAwareMixin, ModuleAwareMixin, TestCase):
"""A test case mixin that creates a temp directory and files in it.