@@ -229,14 +229,21 @@ def skipUnless(cond, msg):
229229 return skip (msg )
230230
231231
232+ class _ExpectedFailure (Exception ):
233+ pass
234+
235+
236+ class _UnexpectedSuccess (Exception ):
237+ pass
238+
239+
232240def expectedFailure (test ):
233241 def test_exp_fail (* args , ** kwargs ):
234242 try :
235243 test (* args , ** kwargs )
236- except :
237- pass
238- else :
239- assert False , "unexpected success"
244+ except Exception :
245+ raise _ExpectedFailure
246+ raise _UnexpectedSuccess
240247
241248 return test_exp_fail
242249
@@ -271,12 +278,33 @@ def run(self, suite: TestSuite):
271278 res .printErrors ()
272279 print ("----------------------------------------------------------------------" )
273280 print ("Ran %d tests\n " % res .testsRun )
274- if res .failuresNum > 0 or res .errorsNum > 0 :
275- print ("FAILED (failures=%d, errors=%d)" % (res .failuresNum , res .errorsNum ))
281+ extras = []
282+ if res .skippedNum > 0 :
283+ extras .append ("skipped=%d" % res .skippedNum )
284+ if res .expectedFailuresNum > 0 :
285+ extras .append ("expected failures=%d" % res .expectedFailuresNum )
286+ if res .unexpectedSuccessesNum > 0 :
287+ extras .append ("unexpected successes=%d" % res .unexpectedSuccessesNum )
288+ if (
289+ res .failuresNum > 0
290+ or res .errorsNum > 0
291+ or res .unexpectedSuccessesNum > 0
292+ ):
293+ parts = [
294+ "failures=%d" % res .failuresNum ,
295+ "errors=%d" % res .errorsNum ,
296+ ]
297+ if res .unexpectedSuccessesNum > 0 :
298+ parts .append ("unexpected successes=%d" % res .unexpectedSuccessesNum )
299+ if res .expectedFailuresNum > 0 :
300+ parts .append ("expected failures=%d" % res .expectedFailuresNum )
301+ if res .skippedNum > 0 :
302+ parts .append ("skipped=%d" % res .skippedNum )
303+ print ("FAILED (%s)" % ", " .join (parts ))
276304 else :
277305 msg = "OK"
278- if res . skippedNum > 0 :
279- msg += " (skipped=%d )" % res . skippedNum
306+ if extras :
307+ msg += " (%s )" % ", " . join ( extras )
280308 print (msg )
281309
282310 return res
@@ -290,14 +318,22 @@ def __init__(self):
290318 self .errorsNum = 0
291319 self .failuresNum = 0
292320 self .skippedNum = 0
321+ self .expectedFailuresNum = 0
322+ self .unexpectedSuccessesNum = 0
293323 self .testsRun = 0
294324 self .errors = []
295325 self .failures = []
296326 self .skipped = []
327+ self .expectedFailures = []
328+ self .unexpectedSuccesses = []
297329 self ._newFailures = 0
298330
299331 def wasSuccessful (self ):
300- return self .errorsNum == 0 and self .failuresNum == 0
332+ return (
333+ self .errorsNum == 0
334+ and self .failuresNum == 0
335+ and self .unexpectedSuccessesNum == 0
336+ )
301337
302338 def printErrors (self ):
303339 if self .errors or self .failures :
@@ -326,10 +362,14 @@ def __add__(self, other):
326362 self .errorsNum += other .errorsNum
327363 self .failuresNum += other .failuresNum
328364 self .skippedNum += other .skippedNum
365+ self .expectedFailuresNum += other .expectedFailuresNum
366+ self .unexpectedSuccessesNum += other .unexpectedSuccessesNum
329367 self .testsRun += other .testsRun
330368 self .errors .extend (other .errors )
331369 self .failures .extend (other .failures )
332370 self .skipped .extend (other .skipped )
371+ self .expectedFailures .extend (other .expectedFailures )
372+ self .unexpectedSuccesses .extend (other .unexpectedSuccesses )
333373 return self
334374
335375
@@ -354,6 +394,19 @@ def _handle_test_exception(
354394 test_result .skipped .append ((current_test , reason ))
355395 print (" skipped:" , reason )
356396 return
397+ elif isinstance (exc , _ExpectedFailure ):
398+ test_result .expectedFailuresNum += 1
399+ test_result .expectedFailures .append ((current_test , "" ))
400+ if verbose :
401+ print (" expected failure" )
402+ return
403+ elif isinstance (exc , _UnexpectedSuccess ):
404+ test_result .unexpectedSuccessesNum += 1
405+ test_result .unexpectedSuccesses .append ((current_test , "" ))
406+ if verbose :
407+ print (" unexpected success" )
408+ test_result ._newFailures += 1
409+ return
357410 elif isinstance (exc , AssertionError ):
358411 test_result .failuresNum += 1
359412 test_result .failures .append ((current_test , ex_str ))
0 commit comments