@@ -1191,9 +1191,9 @@ class DocTestRunner:
11911191 2 tests in _TestClass
11921192 2 tests in _TestClass.__init__
11931193 2 tests in _TestClass.get
1194- 1 tests in _TestClass.square
1194+ 1 test in _TestClass.square
11951195 7 tests in 4 items.
1196- 7 passed and 0 failed .
1196+ 7 passed.
11971197 Test passed.
11981198 TestResults(failed=0, attempted=7)
11991199
@@ -1568,49 +1568,59 @@ def summarize(self, verbose=None):
15681568 """
15691569 if verbose is None :
15701570 verbose = self ._verbose
1571- notests = []
1572- passed = []
1573- failed = []
1571+
1572+ notests , passed , failed = [], [], []
15741573 total_tries = total_failures = total_skips = 0
1575- for item in self . _stats . items ():
1576- name , (failures , tries , skips ) = item
1574+
1575+ for name , (failures , tries , skips ) in self . _stats . items ():
15771576 assert failures <= tries
15781577 total_tries += tries
15791578 total_failures += failures
15801579 total_skips += skips
1580+
15811581 if tries == 0 :
15821582 notests .append (name )
15831583 elif failures == 0 :
15841584 passed .append ((name , tries ))
15851585 else :
1586- failed .append (item )
1586+ failed .append ((name , (failures , tries , skips )))
1587+
15871588 if verbose :
15881589 if notests :
1589- print (f"{ len (notests )} items had no tests:" )
1590+ print (f"{ _n_items (notests )} had no tests:" )
15901591 notests .sort ()
15911592 for name in notests :
15921593 print (f" { name } " )
1594+
15931595 if passed :
1594- print (f"{ len (passed )} items passed all tests:" )
1595- passed .sort ()
1596- for name , count in passed :
1597- print (f" { count :3d} tests in { name } " )
1596+ print (f"{ _n_items (passed )} passed all tests:" )
1597+ for name , count in sorted (passed ):
1598+ s = "" if count == 1 else "s"
1599+ print (f" { count :3d} test{ s } in { name } " )
1600+
15981601 if failed :
15991602 print (self .DIVIDER )
1600- print (f"{ len (failed )} items had failures:" )
1601- failed .sort ()
1602- for name , (failures , tries , skips ) in failed :
1603+ print (f"{ _n_items (failed )} had failures:" )
1604+ for name , (failures , tries , skips ) in sorted (failed ):
16031605 print (f" { failures :3d} of { tries :3d} in { name } " )
1606+
16041607 if verbose :
1605- print (f"{ total_tries } tests in { len (self ._stats )} items." )
1606- print (f"{ total_tries - total_failures } passed and { total_failures } failed." )
1608+ s = "" if total_tries == 1 else "s"
1609+ print (f"{ total_tries } test{ s } in { _n_items (self ._stats )} ." )
1610+
1611+ and_f = f" and { total_failures } failed" if total_failures else ""
1612+ print (f"{ total_tries - total_failures } passed{ and_f } ." )
1613+
16071614 if total_failures :
1608- msg = f"***Test Failed*** { total_failures } failures"
1615+ s = "" if total_failures == 1 else "s"
1616+ msg = f"***Test Failed*** { total_failures } failure{ s } "
16091617 if total_skips :
1610- msg = f"{ msg } and { total_skips } skipped tests"
1618+ s = "" if total_skips == 1 else "s"
1619+ msg = f"{ msg } and { total_skips } skipped test{ s } "
16111620 print (f"{ msg } ." )
16121621 elif verbose :
16131622 print ("Test passed." )
1623+
16141624 return TestResults (total_failures , total_tries , skipped = total_skips )
16151625
16161626 #/////////////////////////////////////////////////////////////////
@@ -1627,6 +1637,15 @@ def merge(self, other):
16271637 d [name ] = (failures , tries , skips )
16281638
16291639
1640+ def _n_items (items : list ) -> str :
1641+ """
1642+ Helper to pluralise the number of items in a list.
1643+ """
1644+ n = len (items )
1645+ s = "" if n == 1 else "s"
1646+ return f"{ n } item{ s } "
1647+
1648+
16301649class OutputChecker :
16311650 """
16321651 A class used to check the whether the actual output from a doctest
0 commit comments