@@ -83,6 +83,16 @@ def capture_stdout_stderr():
8383 sys .stderr = orig_stderr
8484
8585
86+ def _strip_xml (xml , changes ):
87+ doc = etree .fromstring (xml )
88+ for xpath , attributes in changes .items ():
89+ for node in doc .xpath (xpath ):
90+ for attrib in node .attrib .keys ():
91+ if attrib not in attributes :
92+ del node .attrib [attrib ]
93+ return etree .tostring (doc )
94+
95+
8696class XMLTestRunnerTestCase (unittest .TestCase ):
8797 """
8898 XMLTestRunner test case.
@@ -158,6 +168,11 @@ def test_subTest_error(self):
158168 with self .subTest (i = i ):
159169 raise Exception ('this is a subtest' )
160170
171+ def test_subTest_mixed (self ):
172+ for i in range (2 ):
173+ with self .subTest (i = i ):
174+ self .assertLess (i , 1 , msg = 'this is a subtest.' )
175+
161176 class DummyErrorInCallTest (unittest .TestCase ):
162177
163178 def __call__ (self , result ):
@@ -220,21 +235,20 @@ def test_classnames(self):
220235 runner .run (suite )
221236 outdir .seek (0 )
222237 output = outdir .read ()
238+ output = _strip_xml (output , {
239+ '//testsuite' : (),
240+ '//testcase' : ('classname' , 'name' ),
241+ '//failure' : ('message' ,),
242+ })
223243 self .assertRegexpMatches (
224244 output ,
225- r'classname="tests\.testsuite\.(XMLTestRunnerTestCase\.)?DummyTest' .encode ('utf8' ),
226- )
227- self .assertRegexpMatches (
228- output ,
229- r'name="test_pass"' .encode ('utf8' ),
230- )
231- self .assertRegexpMatches (
232- output ,
233- r'classname="tests\.testsuite\.(XMLTestRunnerTestCase\.)?DummySubTest' .encode ('utf8' ),
245+ r'classname="tests\.testsuite\.(XMLTestRunnerTestCase\.)?'
246+ r'DummyTest" name="test_pass"' .encode ('utf8' ),
234247 )
235248 self .assertRegexpMatches (
236249 output ,
237- r'name="test_subTest_pass"' .encode ('utf8' ),
250+ r'classname="tests\.testsuite\.(XMLTestRunnerTestCase\.)?'
251+ r'DummySubTest" name="test_subTest_pass"' .encode ('utf8' ),
238252 )
239253
240254 def test_xmlrunner_non_ascii (self ):
@@ -423,19 +437,20 @@ def test_unittest_subTest_fail(self):
423437 runner .run (suite )
424438 outdir .seek (0 )
425439 output = outdir .read ()
440+ output = _strip_xml (output , {
441+ '//testsuite' : (),
442+ '//testcase' : ('classname' , 'name' ),
443+ '//failure' : ('message' ,),
444+ })
426445 self .assertRegexpMatches (
427446 output ,
428447 br'<testcase classname="tests\.testsuite\.'
429- br'(XMLTestRunnerTestCase\.)?DummySubTest"' )
430- self .assertRegexpMatches (
431- output ,
448+ br'(XMLTestRunnerTestCase\.)?DummySubTest" '
432449 br'name="test_subTest_fail \(i=0\)"' )
433450 self .assertRegexpMatches (
434451 output ,
435452 br'<testcase classname="tests\.testsuite\.'
436- br'(XMLTestRunnerTestCase\.)?DummySubTest"' )
437- self .assertRegexpMatches (
438- output ,
453+ br'(XMLTestRunnerTestCase\.)?DummySubTest" '
439454 br'name="test_subTest_fail \(i=1\)"' )
440455
441456 @unittest .skipIf (not hasattr (unittest .TestCase , 'subTest' ),
@@ -451,21 +466,48 @@ def test_unittest_subTest_error(self):
451466 runner .run (suite )
452467 outdir .seek (0 )
453468 output = outdir .read ()
469+ output = _strip_xml (output , {
470+ '//testsuite' : (),
471+ '//testcase' : ('classname' , 'name' ),
472+ '//failure' : ('message' ,),
473+ })
454474 self .assertRegexpMatches (
455475 output ,
456476 br'<testcase classname="tests\.testsuite\.'
457- br'(XMLTestRunnerTestCase\.)?DummySubTest"' )
458- self .assertRegexpMatches (
459- output ,
477+ br'(XMLTestRunnerTestCase\.)?DummySubTest" '
460478 br'name="test_subTest_error \(i=0\)"' )
461479 self .assertRegexpMatches (
462480 output ,
463481 br'<testcase classname="tests\.testsuite\.'
464- br'(XMLTestRunnerTestCase\.)?DummySubTest"' )
465- self .assertRegexpMatches (
466- output ,
482+ br'(XMLTestRunnerTestCase\.)?DummySubTest" '
467483 br'name="test_subTest_error \(i=1\)"' )
468484
485+
486+ @unittest .skipIf (not hasattr (unittest .TestCase , 'subTest' ),
487+ 'unittest.TestCase.subTest not present.' )
488+ def test_unittest_subTest_mixed (self ):
489+ # test for issue #155
490+ outdir = BytesIO ()
491+ runner = xmlrunner .XMLTestRunner (
492+ stream = self .stream , output = outdir , verbosity = self .verbosity ,
493+ ** self .runner_kwargs )
494+ suite = unittest .TestSuite ()
495+ suite .addTest (self .DummySubTest ('test_subTest_mixed' ))
496+ runner .run (suite )
497+ outdir .seek (0 )
498+ output = outdir .read ()
499+ output = _strip_xml (output , {
500+ '//testsuite' : (),
501+ '//testcase' : ('classname' , 'name' ),
502+ '//failure' : ('message' ,),
503+ })
504+ self .assertNotIn (
505+ 'name="test_subTest_mixed (i=0)"' .encode ('utf8' ),
506+ output )
507+ self .assertIn (
508+ 'name="test_subTest_mixed (i=1)"' .encode ('utf8' ),
509+ output )
510+
469511 @unittest .skipIf (not hasattr (unittest .TestCase , 'subTest' ),
470512 'unittest.TestCase.subTest not present.' )
471513 def test_unittest_subTest_pass (self ):
0 commit comments