@@ -228,14 +228,21 @@ def skipUnless(cond, msg):
228228 return skip (msg )
229229
230230
231+ class _ExpectedFailure (Exception ):
232+ pass
233+
234+
235+ class _UnexpectedSuccess (Exception ):
236+ pass
237+
238+
231239def expectedFailure (test ):
232240 def test_exp_fail (* args , ** kwargs ):
233241 try :
234242 test (* args , ** kwargs )
235- except :
236- pass
237- else :
238- assert False , "unexpected success"
243+ except Exception :
244+ raise _ExpectedFailure
245+ raise _UnexpectedSuccess
239246
240247 return test_exp_fail
241248
@@ -270,12 +277,29 @@ def run(self, suite: TestSuite):
270277 res .printErrors ()
271278 print ("----------------------------------------------------------------------" )
272279 print ("Ran %d tests\n " % res .testsRun )
273- if res .failuresNum > 0 or res .errorsNum > 0 :
274- print ("FAILED (failures=%d, errors=%d)" % (res .failuresNum , res .errorsNum ))
280+ extras = []
281+ if res .skippedNum > 0 :
282+ extras .append ("skipped=%d" % res .skippedNum )
283+ if res .expectedFailuresNum > 0 :
284+ extras .append ("expected failures=%d" % res .expectedFailuresNum )
285+ if res .unexpectedSuccessesNum > 0 :
286+ extras .append ("unexpected successes=%d" % res .unexpectedSuccessesNum )
287+ if (res .failuresNum + res .errorsNum + res .unexpectedSuccessesNum ) > 0 :
288+ parts = [
289+ "failures=%d" % res .failuresNum ,
290+ "errors=%d" % res .errorsNum ,
291+ ]
292+ if res .unexpectedSuccessesNum > 0 :
293+ parts .append ("unexpected successes=%d" % res .unexpectedSuccessesNum )
294+ if res .expectedFailuresNum > 0 :
295+ parts .append ("expected failures=%d" % res .expectedFailuresNum )
296+ if res .skippedNum > 0 :
297+ parts .append ("skipped=%d" % res .skippedNum )
298+ print ("FAILED (%s)" % ", " .join (parts ))
275299 else :
276300 msg = "OK"
277- if res . skippedNum > 0 :
278- msg += " (skipped=%d )" % res . skippedNum
301+ if extras :
302+ msg += " (%s )" % ", " . join ( extras )
279303 print (msg )
280304
281305 return res
@@ -289,14 +313,22 @@ def __init__(self):
289313 self .errorsNum = 0
290314 self .failuresNum = 0
291315 self .skippedNum = 0
316+ self .expectedFailuresNum = 0
317+ self .unexpectedSuccessesNum = 0
292318 self .testsRun = 0
293319 self .errors = []
294320 self .failures = []
295321 self .skipped = []
322+ self .expectedFailures = []
323+ self .unexpectedSuccesses = []
296324 self ._newFailures = 0
297325
298326 def wasSuccessful (self ):
299- return self .errorsNum == 0 and self .failuresNum == 0
327+ return (
328+ self .errorsNum == 0
329+ and self .failuresNum == 0
330+ and self .unexpectedSuccessesNum == 0
331+ )
300332
301333 def printErrors (self ):
302334 if self .errors or self .failures :
@@ -325,10 +357,14 @@ def __add__(self, other):
325357 self .errorsNum += other .errorsNum
326358 self .failuresNum += other .failuresNum
327359 self .skippedNum += other .skippedNum
360+ self .expectedFailuresNum += other .expectedFailuresNum
361+ self .unexpectedSuccessesNum += other .unexpectedSuccessesNum
328362 self .testsRun += other .testsRun
329363 self .errors .extend (other .errors )
330364 self .failures .extend (other .failures )
331365 self .skipped .extend (other .skipped )
366+ self .expectedFailures .extend (other .expectedFailures )
367+ self .unexpectedSuccesses .extend (other .unexpectedSuccesses )
332368 return self
333369
334370
@@ -353,6 +389,19 @@ def _handle_test_exception(
353389 test_result .skipped .append ((current_test , reason ))
354390 print (" skipped:" , reason )
355391 return
392+ elif isinstance (exc , _ExpectedFailure ):
393+ test_result .expectedFailuresNum += 1
394+ test_result .expectedFailures .append ((current_test , "" ))
395+ if verbose :
396+ print (" expected failure" )
397+ return
398+ elif isinstance (exc , _UnexpectedSuccess ):
399+ test_result .unexpectedSuccessesNum += 1
400+ test_result .unexpectedSuccesses .append ((current_test , "" ))
401+ if verbose :
402+ print (" unexpected success" )
403+ test_result ._newFailures += 1
404+ return
356405 elif isinstance (exc , AssertionError ):
357406 test_result .failuresNum += 1
358407 test_result .failures .append ((current_test , ex_str ))
0 commit comments