Commit 3a2b5419 authored by Raymond Hettinger's avatar Raymond Hettinger

Doctest results return a named tuple for readability

parent 064aeb0e
...@@ -99,6 +99,9 @@ import sys, traceback, inspect, linecache, os, re ...@@ -99,6 +99,9 @@ import sys, traceback, inspect, linecache, os, re
import unittest, difflib, pdb, tempfile import unittest, difflib, pdb, tempfile
import warnings import warnings
from StringIO import StringIO from StringIO import StringIO
from collections import namedtuple
TestResults = namedtuple('TestResults', 'failed attempted')
# There are 4 basic classes: # There are 4 basic classes:
# - Example: a <source, want> pair, plus an intra-docstring line number. # - Example: a <source, want> pair, plus an intra-docstring line number.
...@@ -1028,10 +1031,10 @@ class DocTestRunner: ...@@ -1028,10 +1031,10 @@ class DocTestRunner:
>>> tests.sort(key = lambda test: test.name) >>> tests.sort(key = lambda test: test.name)
>>> for test in tests: >>> for test in tests:
... print test.name, '->', runner.run(test) ... print test.name, '->', runner.run(test)
_TestClass -> (0, 2) _TestClass -> TestResults(failed=0, attempted=2)
_TestClass.__init__ -> (0, 2) _TestClass.__init__ -> TestResults(failed=0, attempted=2)
_TestClass.get -> (0, 2) _TestClass.get -> TestResults(failed=0, attempted=2)
_TestClass.square -> (0, 1) _TestClass.square -> TestResults(failed=0, attempted=1)
The `summarize` method prints a summary of all the test cases that The `summarize` method prints a summary of all the test cases that
have been run by the runner, and returns an aggregated `(f, t)` have been run by the runner, and returns an aggregated `(f, t)`
...@@ -1046,7 +1049,7 @@ class DocTestRunner: ...@@ -1046,7 +1049,7 @@ class DocTestRunner:
7 tests in 4 items. 7 tests in 4 items.
7 passed and 0 failed. 7 passed and 0 failed.
Test passed. Test passed.
(0, 7) TestResults(failed=0, attempted=7)
The aggregated number of tried examples and failed examples is The aggregated number of tried examples and failed examples is
also available via the `tries` and `failures` attributes: also available via the `tries` and `failures` attributes:
...@@ -1289,7 +1292,7 @@ class DocTestRunner: ...@@ -1289,7 +1292,7 @@ class DocTestRunner:
# Record and return the number of failures and tries. # Record and return the number of failures and tries.
self.__record_outcome(test, failures, tries) self.__record_outcome(test, failures, tries)
return failures, tries return TestResults(failures, tries)
def __record_outcome(self, test, f, t): def __record_outcome(self, test, f, t):
""" """
...@@ -1421,7 +1424,7 @@ class DocTestRunner: ...@@ -1421,7 +1424,7 @@ class DocTestRunner:
print "***Test Failed***", totalf, "failures." print "***Test Failed***", totalf, "failures."
elif verbose: elif verbose:
print "Test passed." print "Test passed."
return totalf, totalt return TestResults(totalf, totalt)
#///////////////////////////////////////////////////////////////// #/////////////////////////////////////////////////////////////////
# Backward compatibility cruft to maintain doctest.master. # Backward compatibility cruft to maintain doctest.master.
...@@ -1692,7 +1695,7 @@ class DebugRunner(DocTestRunner): ...@@ -1692,7 +1695,7 @@ class DebugRunner(DocTestRunner):
... ''', {}, 'foo', 'foo.py', 0) ... ''', {}, 'foo', 'foo.py', 0)
>>> runner.run(test) >>> runner.run(test)
(0, 1) TestResults(failed=0, attempted=1)
>>> test.globs >>> test.globs
{} {}
...@@ -1822,7 +1825,7 @@ def testmod(m=None, name=None, globs=None, verbose=None, ...@@ -1822,7 +1825,7 @@ def testmod(m=None, name=None, globs=None, verbose=None,
else: else:
master.merge(runner) master.merge(runner)
return runner.failures, runner.tries return TestResults(runner.failures, runner.tries)
def testfile(filename, module_relative=True, name=None, package=None, def testfile(filename, module_relative=True, name=None, package=None,
globs=None, verbose=None, report=True, optionflags=0, globs=None, verbose=None, report=True, optionflags=0,
...@@ -1945,7 +1948,7 @@ def testfile(filename, module_relative=True, name=None, package=None, ...@@ -1945,7 +1948,7 @@ def testfile(filename, module_relative=True, name=None, package=None,
else: else:
master.merge(runner) master.merge(runner)
return runner.failures, runner.tries return TestResults(runner.failures, runner.tries)
def run_docstring_examples(f, globs, verbose=False, name="NoName", def run_docstring_examples(f, globs, verbose=False, name="NoName",
compileflags=None, optionflags=0): compileflags=None, optionflags=0):
...@@ -2004,7 +2007,7 @@ class Tester: ...@@ -2004,7 +2007,7 @@ class Tester:
(f,t) = self.testrunner.run(test) (f,t) = self.testrunner.run(test)
if self.verbose: if self.verbose:
print f, "of", t, "examples failed in string", name print f, "of", t, "examples failed in string", name
return (f,t) return TestResults(f,t)
def rundoc(self, object, name=None, module=None): def rundoc(self, object, name=None, module=None):
f = t = 0 f = t = 0
...@@ -2013,7 +2016,7 @@ class Tester: ...@@ -2013,7 +2016,7 @@ class Tester:
for test in tests: for test in tests:
(f2, t2) = self.testrunner.run(test) (f2, t2) = self.testrunner.run(test)
(f,t) = (f+f2, t+t2) (f,t) = (f+f2, t+t2)
return (f,t) return TestResults(f,t)
def rundict(self, d, name, module=None): def rundict(self, d, name, module=None):
import types import types
......
This diff is collapsed.
...@@ -351,6 +351,9 @@ Core and builtins ...@@ -351,6 +351,9 @@ Core and builtins
Library Library
------- -------
- Doctest now returns results as a named tuple for readability:
(0, 7) --> TestResults(failed=0, attempted=7)
- Issue #846388. re.match is interruptible now, which is particularly - Issue #846388. re.match is interruptible now, which is particularly
good for long regular expression matches. good for long regular expression matches.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment