diff --git a/Lib/unittest/case.py b/Lib/unittest/case.py --- a/Lib/unittest/case.py +++ b/Lib/unittest/case.py @@ -47,9 +47,20 @@ self.skipped = [] self.expectedFailure = None self.errors = [] + self.warnings = [] @contextlib.contextmanager def testPartExecutor(self, test_case, isTest=False): + if isTest: + with warnings.catch_warnings(record=True) as ws: + warnings.simplefilter("always") + yield self._testPartExecutor(test_case, isTest) + for w in ws: + self.warnings.append((test_case, w)) + else: + yield self._testPartExecutor(test_case, isTest) + + def _testPartExecutor(self, test_case, isTest): old_success = self.success self.success = True try: @@ -395,6 +406,15 @@ RuntimeWarning, 2) result.addSuccess(test_case) + def _addWarning(self, result, test_case, warning): + addWarning = getattr(result, 'addWarning', None) + if addWarning is not None: + addWarning(test_case, warning) + else: + warnings.warn("TestResult has no addWarning method, warnings " \ + "not reported", RuntimeWarning, 2) + result.addSuccess(test_case) + @contextlib.contextmanager def subTest(self, msg=None, **params): """Return a context manager that will return the enclosed block @@ -501,6 +521,8 @@ self.doCleanups() for test, reason in outcome.skipped: self._addSkip(result, test, reason) + for test, warning in outcome.warnings: + self._addWarning(result, test, warning) self._feedErrorsToResult(result, outcome.errors) if outcome.success: if expecting_failure: diff --git a/Lib/unittest/result.py b/Lib/unittest/result.py --- a/Lib/unittest/result.py +++ b/Lib/unittest/result.py @@ -41,6 +41,7 @@ self.errors = [] self.testsRun = 0 self.skipped = [] + self.warnings = [] self.expectedFailures = [] self.unexpectedSuccesses = [] self.shouldStop = False @@ -145,6 +146,10 @@ """Called when a test is skipped.""" self.skipped.append((test, reason)) + def addWarning(self, test, warning): + """Called when a test produces a warning.""" + self.warnings.append((test, warning)) + def addExpectedFailure(self, test, err): """Called when an expected failure/error occured.""" self.expectedFailures.append( @@ -202,6 +207,6 @@ return length def __repr__(self): - return ("<%s run=%i errors=%i failures=%i>" % + return ("<%s run=%i errors=%i failures=%i warnings=%i>" % (util.strclass(self.__class__), self.testsRun, len(self.errors), - len(self.failures))) + len(self.failures), len(self.warnings))) diff --git a/Lib/unittest/runner.py b/Lib/unittest/runner.py --- a/Lib/unittest/runner.py +++ b/Lib/unittest/runner.py @@ -87,6 +87,16 @@ self.stream.write("s") self.stream.flush() + def addWarning(self, test, warning): + super(TextTestResult, self).addWarning(test, warning) + if self.showAll: + warnings.showwarning(warning.message, warning.category, + warning.filename, warning.lineno, + file=warning.file, line=warning.line) + elif self.dots: + self.stream.write("w") + self.stream.flush() + def addExpectedFailure(self, test, err): super(TextTestResult, self).addExpectedFailure(test, err) if self.showAll: @@ -180,15 +190,16 @@ (run, run != 1 and "s" or "", timeTaken)) self.stream.writeln() - expectedFails = unexpectedSuccesses = skipped = 0 + expectedFails = unexpectedSuccesses = skipped = warns = 0 try: results = map(len, (result.expectedFailures, result.unexpectedSuccesses, - result.skipped)) + result.skipped, + result.warnings)) except AttributeError: pass else: - expectedFails, unexpectedSuccesses, skipped = results + expectedFails, unexpectedSuccesses, skipped, warns = results infos = [] if not result.wasSuccessful(): @@ -202,6 +213,8 @@ self.stream.write("OK") if skipped: infos.append("skipped=%d" % skipped) + if warns: + infos.append("warnings=%d" % warns) if expectedFails: infos.append("expected failures=%d" % expectedFails) if unexpectedSuccesses: