@@ -156,8 +156,10 @@ def __init__(self, test_result, test_method, outcome=SUCCESS, err=None, subTest=
156156
157157 self .test_name = testcase_name (test_method )
158158 self .test_id = test_method .id ()
159+ self .subDescription = None
159160 if subTest :
160161 self .test_id = subTest .id ()
162+ self .subDescription = subTest ._subDescription ()
161163
162164 def id (self ):
163165 return self .test_id
@@ -174,7 +176,12 @@ def get_description(self):
174176 """
175177 Return a text representation of the test method.
176178 """
177- return self .test_description
179+ description = self .test_description
180+
181+ if self .subDescription is not None :
182+ description += ' ' + self .subDescription
183+
184+ return description
178185
179186 def get_error_info (self ):
180187 """
@@ -337,14 +344,29 @@ def addSubTest(self, testcase, test, err):
337344 Called when a subTest method raises an error.
338345 """
339346 if err is not None :
347+
348+ errorText = None
349+ errorValue = None
350+ errorList = None
351+ if issubclass (err [0 ], test .failureException ):
352+ errorText = 'FAIL'
353+ errorValue = self .infoclass .FAILURE
354+ errorList = self .failures
355+
356+ else :
357+ errorText = 'ERROR'
358+ errorValue = self .infoclass .ERROR
359+ errorList = self .errors
360+
340361 self ._save_output_data ()
362+
341363 testinfo = self .infoclass (
342- self , testcase , self . infoclass . ERROR , err , subTest = test )
343- self . errors .append ((
364+ self , testcase , errorValue , err , subTest = test )
365+ errorList .append ((
344366 testinfo ,
345367 self ._exc_info_to_string (err , testcase )
346368 ))
347- self ._prepare_callback (testinfo , [], 'ERROR' , 'E' )
369+ self ._prepare_callback (testinfo , [], errorText , errorText [ 0 ] )
348370
349371 def addSkip (self , test , reason ):
350372 """
@@ -356,6 +378,36 @@ def addSkip(self, test, reason):
356378 self .skipped .append ((testinfo , reason ))
357379 self ._prepare_callback (testinfo , [], 'SKIP' , 'S' )
358380
381+ def addExpectedFailure (self , test , err ):
382+ """
383+ Missing in xmlrunner, copy-pasted from xmlrunner addError.
384+ """
385+ self ._save_output_data ()
386+
387+ testinfo = self .infoclass (self , test , self .infoclass .ERROR , err )
388+ testinfo .test_exception_name = 'ExpectedFailure'
389+ testinfo .test_exception_message = 'EXPECTED FAILURE: {}' .format (testinfo .test_exception_message )
390+
391+ self .expectedFailures .append ((testinfo , self ._exc_info_to_string (err , test )))
392+ self ._prepare_callback (testinfo , [], 'EXPECTED FAILURE' , 'X' )
393+
394+ @failfast
395+ def addUnexpectedSuccess (self , test ):
396+ """
397+ Missing in xmlrunner, copy-pasted from xmlrunner addSuccess.
398+ """
399+ self ._save_output_data ()
400+
401+ testinfo = self .infoclass (self , test ) # do not set outcome here because it will need exception
402+ testinfo .outcome = self .infoclass .ERROR
403+ # But since we want to have error outcome, we need to provide additional fields:
404+ testinfo .test_exception_name = 'UnexpectedSuccess'
405+ testinfo .test_exception_message = ('UNEXPECTED SUCCESS: This test was marked as expected failure but passed, '
406+ 'please review it' )
407+
408+ self .unexpectedSuccesses .append (testinfo )
409+ self ._prepare_callback (testinfo , [], 'UNEXPECTED SUCCESS' , 'U' )
410+
359411 def printErrorList (self , flavour , errors ):
360412 """
361413 Writes information about the FAIL or ERROR to the stream.
0 commit comments