Python Cookbook 2Nd Edition Jun 1002005 [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Python Cookbook 2Nd Edition Jun 1002005 [Electronic resources] - نسخه متنی

David Ascher, Alex Martelli, Anna Ravenscroft

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید







Recipe 8.10. Using doctest with unittest in Python 2.4


Credit: John Nielsen


Problem




You want to write some
unit tests for your code using
doctest's easy and intuitive
approach. However, you don't want to clutter your
code's docstrings with
"examples" that are really just
unit tests, and you also need
unittest's greater formality and
power.


Solution


Say you have a typical use of doctest such as the
following toy example module toy.py:

def add(a, b):
"" Add two arbitrary objects and return their sum.
>>> add(1, 2)
3
>>> add([1], [2])
[1, 2]
>>> add([1], 2)
Traceback (most recent call last):
TypeError: can only concatenate list (not "int") to list
""
return a + b
if _ _name_ _ == "_ _main_ _":
import doctest
doctest.testmod( )

Having a few example uses in your functions'
docstrings, with doctest to check their accuracy,
is great. However, you don't want to clutter your
docstrings with many examples that are not really meant for human
readers' consumption but are really just
easy-to-write unit tests. With Python 2.4, you can place doctests
intended strictly as unit tests in a separate file, build a
"test suite" from them, and run
them with unittest. For example, place in file
test_toy.txt the following lines (no quoting
needed):

>>> import toy
>>> toy.add('a', 'b')
'ab'
>>> toy.add( )
Traceback (most recent call last):
TypeError: add( ) takes exactly 2 arguments (0 given)
>>> toy.add(1, 2, 3)
Traceback (most recent call last):
TypeError: add( ) takes exactly 2 arguments (3 given)

and add at the end of toy.py a few more lines:

    import unittest
suite = doctest.DocFileSuite('test_toy.txt')
unittest.TextTestRunner( ).run(suite)

Now, running python toy.py at a shell command
prompt produces the following output:

.
----------------------------------------------------------------------
Ran 1 test in 0.003s
OK


Discussion


The doctest module of the Python Standard Library
is a simple, highly productive way to produce a plain but useful
bunch of unit tests for your code. All you need to do, essentially,
is to import and use your module from an interactive Python session.
Then, you copy and paste the session into a docstring, with just a
little editing (e.g. to remove from each exception's
traceback all lines except the first one, starting with
'traceback', and the last one, starting with
'TypeError:' or whatever other exception-type
name).


Docstrings



Documentation strings
(docstrings) are an important feature that
Python offers to help you document your code. Any module, class,
function or method can have a string literal as its very first
"statement". If so, then Python
considers that string to be the docstring for the module, class,
function, or method in question and saves it as the _ _doc_
_
attribute of the respective object. Modules, classes,
functions, and methods that lack docstrings have
None as the value of their _ _doc_
_
attribute.

In Python's interactive interpreter, you can examine
the "docstring" of an object, as
well as other helpful information about the object, with the command
help(theobject). Module pydoc,
in the Python Standard Library, uses docstrings, as well as
introspection, to generate and optionally serve web pages of
information about modules, classes, functions, and methods. (See
http://pydoc.org/ for a web site
containing pydoc-generated documentation about the
Python Standard Library as well as the standard Python online
documentation.)

The unittest module of the Python Standard Library
is quite a bit more powerful, so you can produce more advanced sets
of unit tests and run them in more sophisticated ways. Writing the
unit tests is not quite as simple and fast as with
doctest.

Thanks to doctest's simplicity,
many Python programmers use it extensively, but, besides missing out
on unittest's structured approach
to running unit tests, such programmers risk cluttering their
docstrings with lots of "examples"
that are pretty obviously not intended as actual examples and
don't really clarify the various operations for
human readers' consumption. Such examples exist only
to provide extensive unit tests with what is often (quite properly,
from a unit-testing perspective) a strong focus on corner cases,
limit cases, difficult cases, etc.

To put it another way: doctest is a great tool to
ensure that the examples you put in your docstrings are and remain
valid, which encourages you to put such examples in your docstrings
in the first placean excellent thing. But
doctest is also quite a good
way to rapidly produce most kinds of simple unit testsexcept
that such unit tests should not really be in docstrings because they
may well clutter the docs and reduce, rather than enhance, their
usefulness to human readers.

Python 2.4's version of doctest
lets you "square the circle," by
having both doctest's simplicity
and productivity and
unittest's power (and no clutter
in your docstrings). Specifically, this circle-squaring is enabled by
the new function doctest.DocFileSuite. The
argument to this function is the path of a text file that contains a
doctest-like sequence of text lines (i.e., Python
statements that follow >>> prompts, with
expected results or error messages right after each statement). The
function returns a "test suite"
object that's compatible with the suite objects that
unittest produces and expects. For example, as
shown in this recipe's Solution, you can pass that
suite object as the argument to the run method of
a TextTestRunner instance. Note that the text file
you pass to doctest.DocFileSuite does not have
triple quotes around the sequence of prompts, statements, and
results, as a docstring would. Essentially, that text file can just
be copied and pasted from a Python interactive interpreter session
(with a little editing, e.g., of exceptions'
tracebacks, as previously mentioned).


See Also


Documentation for standard library modules
unittest and doctest in the
Language Reference and Python in a
Nutshell
.


/ 394