diff options
-rw-r--r-- | Lib/doctest.py | 155 |
1 files changed, 18 insertions, 137 deletions
diff --git a/Lib/doctest.py b/Lib/doctest.py index 56bf551..21cbc32 100644 --- a/Lib/doctest.py +++ b/Lib/doctest.py @@ -6,16 +6,15 @@ # Provided as-is; use at your own risk; no warranty; no promises; enjoy! -# [XX] This docstring is out-of-date: r"""Module doctest -- a framework for running examples in docstrings. NORMAL USAGE -In normal use, end each module M with: +In simplest use, end each module M to be tested with: def _test(): - import doctest, M # replace M with your module's name - return doctest.testmod(M) # ditto + import doctest + return doctest.testmod() if __name__ == "__main__": _test() @@ -37,14 +36,20 @@ python M.py -v and a detailed report of all examples tried is printed to stdout, along with assorted summaries at the end. -You can force verbose mode by passing "verbose=1" to testmod, or prohibit -it by passing "verbose=0". In either of those cases, sys.argv is not +You can force verbose mode by passing "verbose=True" to testmod, or prohibit +it by passing "verbose=False". In either of those cases, sys.argv is not examined by testmod. In any case, testmod returns a 2-tuple of ints (f, t), where f is the number of docstring examples that failed and t is the total number of docstring examples attempted. +There are a variety of other ways to run doctests, including integration +with the unittest framework, and support for running non-Python text +files containing doctests. There are also many ways to override parts +of doctest's default behaviors. See the Library Reference Manual for +details. + WHICH DOCSTRINGS ARE EXAMINED? @@ -59,27 +64,13 @@ WHICH DOCSTRINGS ARE EXAMINED? + If M.__test__ exists and "is true", it must be a dict, and each entry maps a (string) name to a function object, class object, or string. Function and class object docstrings found from M.__test__ - are searched even if the name is private, and strings are searched - directly as if they were docstrings. In output, a key K in M.__test__ - appears with name + are searched, and strings are searched directly as if they were docstrings. + In output, a key K in M.__test__ appears with name <name of M>.__test__.K Any classes found are recursively searched similarly, to test docstrings in -their contained methods and nested classes. All names reached from -M.__test__ are searched. - -Optionally, functions with private names can be skipped (unless listed in -M.__test__) by supplying a function to the "isprivate" argument that will -identify private functions. For convenience, one such function is -supplied. docttest.is_private considers a name to be private if it begins -with an underscore (like "_my_func") but doesn't both begin and end with -(at least) two underscores (like "__init__"). By supplying this function -or your own "isprivate" function to testmod, the behavior can be customized. - -If you want to test docstrings in objects with private names too, stuff -them into an M.__test__ dict, or see ADVANCED USAGE below (e.g., pass your -own isprivate function to Tester's constructor, or call the rundoc method -of a Tester instance). +their contained methods and nested classes. + WHAT'S THE EXECUTION CONTEXT? @@ -96,48 +87,6 @@ You can force use of your own dict as the execution context by passing M.__dict__ merged with the globals from other imported modules. -WHAT IF I WANT TO TEST A WHOLE PACKAGE? - -Piece o' cake, provided the modules do their testing from docstrings. -Here's the test.py I use for the world's most elaborate Rational/ -floating-base-conversion pkg (which I'll distribute some day): - -from Rational import Cvt -from Rational import Format -from Rational import machprec -from Rational import Rat -from Rational import Round -from Rational import utils - -modules = (Cvt, - Format, - machprec, - Rat, - Round, - utils) - -def _test(): - import doctest - import sys - verbose = "-v" in sys.argv - for mod in modules: - doctest.testmod(mod, verbose=verbose, report=0) - doctest.master.summarize() - -if __name__ == "__main__": - _test() - -IOW, it just runs testmod on all the pkg modules. testmod remembers the -names and outcomes (# of failures, # of tries) for each item it's seen, and -passing "report=0" prevents it from printing a summary in verbose mode. -Instead, the summary is delayed until all modules have been tested, and -then "doctest.master.summarize()" forces the summary at the end. - -So this is very nice in practice: each module can be tested individually -with almost no work beyond writing up docstring examples, and collections -of modules can be tested too as a unit with no more work than the above. - - WHAT ABOUT EXCEPTIONS? No problem, as long as the only output generated by the example is the @@ -149,25 +98,10 @@ traceback itself. For example: ValueError: list.remove(x): x not in list >>> -Note that only the exception type and value are compared (specifically, -only the last line in the traceback). - +Note that only the exception type and value are compared. -ADVANCED USAGE -doctest.testmod() captures the testing policy I find most useful most -often. You may want other policies. - -testmod() actually creates a local instance of class doctest.Tester, runs -appropriate methods of that class, and merges the results into global -Tester instance doctest.master. - -You can create your own instances of doctest.Tester, and so build your own -policies, or even run methods of doctest.master directly. See -doctest.Tester.__doc__ for details. - - -SO WHAT DOES A DOCSTRING EXAMPLE LOOK LIKE ALREADY!? +SO WHAT DOES A DOCTEST EXAMPLE LOOK LIKE ALREADY!? Oh ya. It's easy! In most cases a copy-and-paste of an interactive console session works fine -- just make sure the leading whitespace is @@ -197,9 +131,6 @@ containing the code, and the expected output (if any) extends to the next Bummers: -+ Expected output cannot contain an all-whitespace line, since such a line - is taken to signal the end of expected output. - + Output to stdout is captured, but not output to stderr (exception tracebacks are captured via a different means). @@ -234,57 +165,7 @@ and as many leading whitespace characters are stripped from the expected output as appeared in the initial ">>>" line that triggered it. If you execute this very file, the examples above will be found and -executed, leading to this output in verbose mode: - -Running doctest.__doc__ -Trying: [1, 2, 3].remove(42) -Expecting: -Traceback (most recent call last): - File "<stdin>", line 1, in ? -ValueError: list.remove(x): x not in list -ok -Trying: x = 12 -Expecting: nothing -ok -Trying: x -Expecting: 12 -ok -Trying: -if x == 13: - print "yes" -else: - print "no" - print "NO" - print "NO!!!" -Expecting: -no -NO -NO!!! -ok -... and a bunch more like that, with this summary at the end: - -5 items had no tests: - doctest.Tester.__init__ - doctest.Tester.run__test__ - doctest.Tester.summarize - doctest.run_docstring_examples - doctest.testmod -12 items passed all tests: - 8 tests in doctest - 6 tests in doctest.Tester - 10 tests in doctest.Tester.merge - 14 tests in doctest.Tester.rundict - 3 tests in doctest.Tester.rundoc - 3 tests in doctest.Tester.runstring - 2 tests in doctest.__test__._TestClass - 2 tests in doctest.__test__._TestClass.__init__ - 2 tests in doctest.__test__._TestClass.get - 1 tests in doctest.__test__._TestClass.square - 2 tests in doctest.__test__.string - 7 tests in doctest.is_private -60 tests in 17 items. -60 passed and 0 failed. -Test passed. +executed. """ __all__ = [ |