8000 bpo-14265: Adds fully qualified test name to unittest output (GH-32138) · python/cpython@755be9b · GitHub
[go: up one dir, main page]

Skip to content

Commit 755be9b

Browse files
bpo-14265: Adds fully qualified test name to unittest output (GH-32138)
Co-authored-by: Andrew Svetlov <andrew.svetlov@gmail.com>
1 parent 356997c commit 755be9b

File tree

5 files changed

+63
-49
lines changed

5 files changed

+63
-49
lines changed

Doc/library/unittest.rst

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,9 @@ line, the above script produces an output that looks like this::
139139
Passing the ``-v`` option to your test script will instruct :func:`unittest.main`
140140
to enable a higher level of verbosity, and produce the following output::
141141

142-
test_isupper (__main__.TestStringMethods) ... ok
143-
test_split (__main__.TestStringMethods) ... ok
144-
test_upper (__main__.TestStringMethods) ... ok
142+
test_isupper (__main__.TestStringMethods.test_isupper) ... ok
143+
test_split (__main__.TestStringMethods.test_split) ... ok
144+
test_upper (__main__.TestStringMethods.test_upper) ... ok
145145

146146
----------------------------------------------------------------------
147147
Ran 3 tests in 0.001s
@@ -565,10 +565,10 @@ Basic skipping looks like this::
565565

566566
This is the output of running the example above in verbose mode::
567567

568-
test_format (__main__.MyTestCase) ... skipped 'not supported in this library version'
569-
test_nothing (__main__.MyTestCase) ... skipped 'demonstrating skipping'
570-
test_maybe_skipped (__main__.MyTestCase) ... skipped 'external resource not available'
571-
test_windows_support (__main__.MyTestCase) ... skipped 'requires Windows'
568+
test_format (__main__.MyTestCase.test_format) ... skipped 'not supported in this library version'
569+
test_nothing (__main__.MyTestCase.test_nothing) ... skipped 'demonstrating skipping'
570+
test_maybe_skipped (__main__.MyTestCase.test_maybe_skipped) ... skipped 'external resource not available'
571+
test_windows_support (__main__.MyTestCase.test_windows_support) ... skipped 'requires Windows'
572572

573573
----------------------------------------------------------------------
574574
Ran 4 tests in 0.005s
@@ -661,35 +661,41 @@ For example, the following test::
661661
will produce the following output::
662662

663663
======================================================================
664-
FAIL: test_even (__main__.NumbersTest) (i=1)
664+
FAIL: test_even (__main__.NumbersTest.test_even) (i=1)
665+
Test that numbers between 0 and 5 are all even.
665666
----------------------------------------------------------------------
666667
Traceback (most recent call last):
667-
File "subtests.py", line 32, in test_even
668+
File "subtests.py", line 11, in test_even
668669
self.assertEqual(i % 2, 0)
670+
^^^^^^^^^^^^^^^^^^^^^^^^^^
669671
AssertionError: 1 != 0
670672

671673
======================================================================
672-
FAIL: test_even (__main__.NumbersTest) (i=3)
674+
FAIL: test_even (__main__.NumbersTest.test_even) (i=3)
675+
Test that numbers between 0 and 5 are all even.
673676
----------------------------------------------------------------------
674677
Traceback (most recent call last):
675-
File "subtests.py", line 32, in test_even
678+
File "subtests.py", line 11, in test_even
676679
self.assertEqual(i % 2, 0)
680+
^^^^^^^^^^^^^^^^^^^^^^^^^^
677681
AssertionError: 1 != 0
678682

679683
======================================================================
680-
FAIL: test_even (__main__.NumbersTest) (i=5)
684+
FAIL: test_even (__main__.NumbersTest.test_even) (i=5)
685+
Test that numbers between 0 and 5 are all even.
681686
----------------------------------------------------------------------
682687
Traceback (most recent call last):
683-
File "subtests.py", line 32, in test_even
688+
File "subtests.py", line 11, in test_even
684689
self.assertEqual(i % 2, 0)
690+
^^^^^^^^^^^^^^^^^^^^^^^^^^
685691
AssertionError: 1 != 0
686692

687693
Without using a subtest, execution would stop after the first failure,
688694
and the error would be less easy to diagnose because the value of ``i``
689695
wouldn't be displayed::
690696

691697
======================================================================
692-
FAIL: test_even (__main__.NumbersTest)
698+
FAIL: test_even (__main__.NumbersTest.test_even)
693699
----------------------------------------------------------------------
694700
Traceback (most recent call last):
695701
File "subtests.py", line 32, in test_even

Lib/unittest/case.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,7 @@ def __hash__(self):
478478
return hash((type(self), self._testMethodName))
479479

480480
def __str__(self):
481-
return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
481+
return "%s (%s.%s)" % (self._testMethodName, strclass(self.__class__), self._testMethodName)
482482

483483
def __repr__(self):
484484
return "<%s testMethod=%s>" % \

Lib/unittest/test/test_result.py

Lines changed: 40 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -423,32 +423,34 @@ def testGetDescriptionWithoutDocstring(self):
423423
self.assertEqual(
424424
result.getDescription(self),
425425
'testGetDescriptionWithoutDocstring (' + __name__ +
426-
'.Test_TextTestResult)')
426+
'.Test_TextTestResult.testGetDescriptionWithoutDocstring)')
427427

428428
def testGetSubTestDescriptionWithoutDocstring(self):
429429
with self.subTest(foo=1, bar=2):
430430
result = unittest.TextTestResult(None, True, 1)
431431
self.assertEqual(
432432
result.getDescription(self._subtest),
433433
'testGetSubTestDescriptionWithoutDocstring (' + __name__ +
434-
'.Test_TextTestResult) (foo=1, bar=2)')
434+
'.Test_TextTestResult.testGetSubTestDescriptionWithoutDocstring) (foo=1, bar=2)')
435+
435436
with self.subTest('some message'):
436437
result = unittest.TextTestResult(None, True, 1)
437438
self.assertEqual(
438439
result.getDescription(self._subtest),
439440
'testGetSubTestDescriptionWithoutDocstring (' + __name__ +
440-
'.Test_TextTestResult) [some message]')
441+
'.Test_TextTestResult.testGetSubTestDescriptionWithoutDocstring) [some message]')
441442

442443
def testGetSubTestDescriptionWithoutDocstringAndParams(self):
443444
with self.subTest():
444445
result = unittest.TextTestResult(None, True, 1)
445446
self.assertEqual(
446447
result.getDescription(self._subtest),
447448
'testGetSubTestDescriptionWithoutDocstringAndParams '
448-
'(' + __name__ + '.Test_TextTestResult) (<subtest>)')
449+
'(' + __name__ + '.Test_TextTestResult.testGetSubTestDescriptionWithoutDocstringAndParams) '
450+
'(<subtest>)')
449451

450452
def testGetSubTestDescriptionForFalsyValues(self):
451-
expected = 'testGetSubTestDescriptionForFalsyValues (%s.Test_TextTestResult) [%s]'
453+
expected = 'testGetSubTestDescriptionForFalsyValues (%s.Test_TextTestResult.testGetSubTestDescriptionForFalsyValues) [%s]'
452454
result = unittest.TextTestResult(None, True, 1)
453455
for arg in [0, None, []]:
454456
with self.subTest(arg):
@@ -464,7 +466,8 @@ def testGetNestedSubTestDescriptionWithoutDocstring(self):
464466
self.assertEqual(
465467
result.getDescription(self._subtest),
466468
'testGetNestedSubTestDescriptionWithoutDocstring '
467-
'(' + __name__ + '.Test_TextTestResult) (baz=2, bar=3, foo=1)')
469+
'(' + __name__ + '.Test_TextTestResult.testGetNestedSubTestDescriptionWithoutDocstring) '
470+
'(baz=2, bar=3, foo=1)')
468471

469472
def testGetDuplicatedNestedSubTestDescriptionWithoutDocstring(self):
470473
with self.subTest(foo=1, bar=2):
@@ -473,7 +476,7 @@ def testGetDuplicatedNestedSubTestDescriptionWithoutDocstring(self):
473476
self.assertEqual(
474477
result.getDescription(self._subtest),
475478
'testGetDuplicatedNestedSubTestDescriptionWithoutDocstring '
476-
'(' + __name__ + '.Test_TextTestResult) (baz=3, bar=4, foo=1)')
479+
'(' + __name__ + '.Test_TextTestResult.testGetDuplicatedNestedSubTestDescriptionWithoutDocstring) (baz=3, bar=4, foo=1)')
477480

478481
@unittest.skipIf(sys.flags.optimize >= 2,
479482
"Docstrings are omitted with -O2 and above")
@@ -483,7 +486,7 @@ def testGetDescriptionWithOneLineDocstring(self):
483486
self.assertEqual(
484487
result.getDescription(self),
485488
('testGetDescriptionWithOneLineDocstring '
486-
'(' + __name__ + '.Test_TextTestResult)\n'
489+
'(' + __name__ + '.Test_TextTestResult.testGetDescriptionWithOneLineDocstring)\n'
487490
'Tests getDescription() for a method with a docstring.'))
488491

489492
@unittest.skipIf(sys.flags.optimize >= 2,
@@ -495,7 +498,9 @@ def testGetSubTestDescriptionWithOneLineDocstring(self):
495498
self.assertEqual(
496499
result.getDescription(self._subtest),
497500
('testGetSubTestDescriptionWithOneLineDocstring '
498-
'(' + __name__ + '.Test_TextTestResult) (foo=1, bar=2)\n'
501+
'(' + __name__ + '.Test_TextTestResult.testGetSubTestDescriptionWithOneLineDocstring) '
502+
'(foo=1, bar=2)\n'
503+
499504
'Tests getDescription() for a method with a docstring.'))
500505

501506
@unittest.skipIf(sys.flags.optimize >= 2,
@@ -508,7 +513,7 @@ def testGetDescriptionWithMultiLineDocstring(self):
508513
self.assertEqual(
509514
result.getDescription(self),
510515
('testGetDescriptionWithMultiLineDocstring '
511-
'(' + __name__ + '.Test_TextTestResult)\n'
516+
'(' + __name__ + '.Test_TextTestResult.testGetDescriptionWithMultiLineDocstring)\n'
512517
'Tests getDescription() for a method with a longer '
513518
'docstring.'))
514519

@@ -523,7 +528,8 @@ def testGetSubTestDescriptionWithMultiLineDocstring(self):
523528
self.assertEqual(
524529
result.getDescription(self._subtest),
525530
('testGetSubTestDescriptionWithMultiLineDocstring '
526-
'(' + __name__ + '.Test_TextTestResult) (foo=1, bar=2)\n'
531+
'(' + __name__ + '.Test_TextTestResult.testGetSubTestDescriptionWithMultiLineDocstring) '
532+
'(foo=1, bar=2)\n'
527533
'Tests getDescription() for a method with a longer '
528534
'docstring.'))
529535

@@ -582,36 +588,36 @@ def testDotsOutput(self):
582588
def testLongOutput(self):
583589
classname = f'{__name__}.{self.Test.__qualname__}'
584590
self.assertEqual(self._run_test('testSuccess', 2),
585-
f'testSuccess ({classname}) ... ok\n')
591+
f'testSuccess ({classname}.testSuccess) ... ok\n')
586592
self.assertEqual(self._run_test('testSkip', 2),
587-
f"testSkip ({classname}) ... skipped 'skip'\n")
593+
f"testSkip ({classname}.testSkip) ... skipped 'skip'\n")
588594
self.assertEqual(self._run_test('testFail', 2),
589-
f'testFail ({classname}) ... FAIL\n')
595+
f'testFail ({classname}.testFail) ... FAIL\n')
590596
self.assertEqual(self._run_test('testError', 2),
591-
f'testError ({classname}) ... ERROR\n')
597+
f'testError ({classname}.testError) ... ERROR\n')
592598
self.assertEqual(self._run_test('testExpectedFailure', 2),
593-
f'testExpectedFailure ({classname}) ... expected failure\n')
599+
f'testExpectedFailure ({classname}.testExpectedFailure) ... expected failure\n')
594600
self.assertEqual(self._run_test('testUnexpectedSuccess', 2),
595-
f'testUnexpectedSuccess ({classname}) ... unexpected success\n')
601+
f'testUnexpectedSuccess ({classname}.testUnexpectedSuccess) ... unexpected success\n')
596602

597603
def testDotsOutputSubTestSuccess(self):
598604
self.assertEqual(self._run_test('testSubTestSuccess', 1), '.')
599605

600606
def testLongOutputSubTestSuccess(self):
601607
classname = f'{__name__}.{self.Test.__qualname__}'
602608
self.assertEqual(self._run_test('testSubTestSuccess', 2),
603-
f'testSubTestSuccess ({classname}) ... ok\n')
609+
f'testSubTestSuccess ({classname}.testSubTestSuccess) ... ok\n')
604610

605611
def testDotsOutputSubTestMixed(self):
606612
self.assertEqual(self._run_test('testSubTestMixed', 1), 'sFE')
607613

608614
def testLongOutputSubTestMixed(self):
609615
classname = f'{__name__}.{self.Test.__qualname__}'
610616
self.assertEqual(self._run_test('testSubTestMixed', 2),
611-
f'testSubTestMixed ({classname}) ... \n'
612-
f" testSubTestMixed ({classname}) [skip] (b=2) ... skipped 'skip'\n"
613-
f' testSubTestMixed ({classname}) [fail] (c=3) ... FAIL\n'
614-
f' testSubTestMixed ({classname}) [error] (d=4) ... ERROR\n')
617+
f'testSubTestMixed ({classname}.testSubTestMixed) ... \n'
618+
f" testSubTestMixed ({classname}.testSubTestMixed) [skip] (b=2) ... skipped 'skip'\n"
619+
f' testSubTestMixed ({classname}.testSubTestMixed) [fail] (c=3) ... FAIL\n'
620+
f' testSubTestMixed ({classname}.testSubTestMixed) [error] (d=4) ... ERROR\n')
615621

616622
def testDotsOutputTearDownFail(self):
617623
out = self._run_test('testSuccess', 1, AssertionError('fail'))
@@ -627,19 +633,19 @@ def testLongOutputTearDownFail(self):
627633
classname = f'{__name__}.{self.Test.__qualname__}'
628634
out = self._run_test('testSuccess', 2, AssertionError('fail'))
629635
self.assertEqual(out,
630-
f'testSuccess ({classname}) ... FAIL\n')
636+
f'testSuccess ({classname}.testSuccess) ... FAIL\n')
631637
out = self._run_test('testError', 2, AssertionError('fail'))
632638
self.assertEqual(out,
633-
f'testError ({classname}) ... ERROR\n'
634-
f'testError ({classname}) ... FAIL\n')
639+
f'testError ({classname}.testError) ... ERROR\n'
640+
f'testError ({classname}.testError) ... FAIL\n')
635641
out = self._run_test('testFail', 2, Exception('error'))
636642
self.assertEqual(out,
637-
f'testFail ({classname}) ... FAIL\n'
638-
f'testFail ({classname}) ... ERROR\n')
643+
f'testFail ({classname}.testFail) ... FAIL\n'
644+
f'testFail ({classname}.testFail) ... ERROR\n')
639645
out = self._run_test('testSkip', 2, AssertionError('fail'))
640646
self.assertEqual(out,
641-
f"testSkip ({classname}) ... skipped 'skip'\n"
642-
f'testSkip ({classname}) ... FAIL\n')
647+
f"testSkip ({classname}.testSkip) ... skipped 'skip'\n"
648+
f'testSkip ({classname}.testSkip) ... FAIL\n')
643649

644650

645651
classDict = dict(unittest.TestResult.__dict__)
@@ -852,7 +858,7 @@ def test_foo(self):
852858
expected_out = '\nStdout:\nset up\n'
853859
self.assertEqual(stdout.getvalue(), expected_out)
854860
self.assertEqual(len(result.errors), 1)
855-
description = f'test_foo ({strclass(Foo)})'
861+
description = f'test_foo ({strclass(Foo)}.test_foo)'
856862
test_case, formatted_exc = result.errors[0]
857863
self.assertEqual(str(test_case), description)
858864
self.assertIn('ZeroDivisionError: division by zero', formatted_exc)
@@ -874,7 +880,7 @@ def test_foo(self):
874880
expected_out = '\nStdout:\ntear down\n'
875881
self.assertEqual(stdout.getvalue(), expected_out)
876882
self.assertEqual(len(result.errors), 1)
877-
description = f'test_foo ({strclass(Foo)})'
883+
description = f'test_foo ({strclass(Foo)}.test_foo)'
878884
test_case, formatted_exc = result.errors[0]
879885
self.assertEqual(str(test_case), description)
880886
self.assertIn('ZeroDivisionError: division by zero', formatted_exc)
@@ -897,7 +903,7 @@ def test_foo(self):
897903
expected_out = '\nStdout:\nset up\ndo cleanup2\ndo cleanup1\n'
898904
self.assertEqual(stdout.getvalue(), expected_out)
899905
self.assertEqual(len(result.errors), 2)
900-
description = f'test_foo ({strclass(Foo)})'
906+
description = f'test_foo ({strclass(Foo)}.test_foo)'
901907
test_case, formatted_exc = result.errors[0]
902908
self.assertEqual(str(test_case), description)
903909
self.assertIn('ValueError: bad cleanup2', formatted_exc)
@@ -928,7 +934,7 @@ def test_foo(self):
928934
expected_out = '\nStdout:\nset up\ndo cleanup2\ndo cleanup1\n'
929935
self.assertEqual(stdout.getvalue(), expected_out)
930936
self.assertEqual(len(result.errors), 3)
931-
description = f'test_foo ({strclass(Foo)})'
937+
description = f'test_foo ({strclass(Foo)}.test_foo)'
932938
test_case, formatted_exc = result.errors[0]
933939
self.assertEqual(str(test_case), description)
934940
self.assertIn('ZeroDivisionError: division by zero', formatted_exc)
@@ -971,7 +977,7 @@ def test_foo(self):
971977
expected_out = '\nStdout:\nset up\ntear down\ndo cleanup2\ndo cleanup1\n'
972978
self.assertEqual(stdout.getvalue(), expected_out)
973979
self.assertEqual(len(result.errors), 3)
974-
description = f'test_foo ({strclass(Foo)})'
980+
description = f'test_foo ({strclass(Foo)}.test_foo)'
975981
test_case, formatted_exc = result.errors[0]
976982
self.assertEqual(str(test_case), description)
977983
self.assertIn('ZeroDivisionError: division by zero', formatted_exc)

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,7 @@ Daniel Evers
516516
evilzero
517517
Winston Ewert
518518
Greg Ewing
519+
Sam Ezeh
519520
Martijn Faassen
520521
Clovis Fabricio
521522
Andreas Faerber
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Adds the fully qualified test name to unittest output

0 commit comments

Comments
 (0)
0