[Checkins]
SVN: Sandbox/philikon/foundation/maintaining-software.txt
Incorporate feedback from Jim Fulton
Philipp von Weitershausen
philikon at philikon.de
Mon Aug 27 17:56:13 EDT 2007
Log message for revision 79301:
Incorporate feedback from Jim Fulton
Changed:
U Sandbox/philikon/foundation/maintaining-software.txt
-=-
Modified: Sandbox/philikon/foundation/maintaining-software.txt
===================================================================
--- Sandbox/philikon/foundation/maintaining-software.txt 2007-08-27 21:54:48 UTC (rev 79300)
+++ Sandbox/philikon/foundation/maintaining-software.txt 2007-08-27 21:56:12 UTC (rev 79301)
@@ -144,39 +144,86 @@
All software should be accompanied by automated tests. Packages that
provide integrated components for the web should preferrably be
-accompanied by both unit tests and integration/functional tests.
+accompanied by both unit tests and integration/functional tests. The
+definition of test cases should be done in ``tests`` packages or
+modules.
-Doctests_ can be used to test a package and document/demonstrate its
-features at the same time. They are therefore recommended over the
-classic ``unittest.TestCase``-based tests. Since doctests not only
-contain the testing aspect but also the documentation aspect, they
-likely take more effort to write than regular, undocumented tests. In
-doctests, each stanza of test code should be accompanied by a
-paragraph explaning what's going on. In such paragraphs, it is
-recommended to use first person plural ("we") or second person ("you")
-to involve the reader. It usually helps outlining use cases for the
-software, especially when tests are written *before* the
-implementation.
-
-The definition of test cases should be done in ``tests`` packages or
-modules. Doctests should be valid reStructuredText and preferrably
-placed in text files rather than in docstrings. The doctest files
-should be named aptly so that developers can easily associate them
-with the code in question, have the file extension ``.txt`` and are
-best placed next to code in question. Edge-case tests should be
-clearly separated from the main doctests so that the novice reader
-isn't confused by the varying level of detail.
-
Before checking modifications into the trunk or a release branch, all
existing tests for the package must pass. Furthermore, when adding a
feature, modifying the behaviour of a component or fixing a bug, a
test exercising the change must be supplied as well. There would
otherwise be no reproducible way of knowing whether the new code
-actually worked.
+actually worked. In terms of automated tests, think "Untested code is
+broken code."
-In terms of automated tests, think "Untested code is broken code."
-Writing tests takes time, but it's time well-spent.
+Tests should be written in a fairly literate way with documentation of
+the test itself. That is to ensure that the intent of each test is
+clear and obvious to any other developer. One can use
+``unittest.TestCase`` as a test harness, or preferrably doctests_.
+We can differentiate two kinds of (doc)tests which should be separated
+from each other clearly:
+
+- **Executable documentation**
+
+ Since automated tests have to exercise every feature of the software
+ anyway, they might just as well serve as the software's
+ documentation. Doctests_ work especially well for this kind of
+ tests because they contain documentation text and test code at the
+ same time. Here's an example of executable documentation in doctest
+ format::
+
+ Defining interfaces
+ ===================
+
+ Interfaces are defined using Python class statements::
+
+ >>> import zope.interface
+ >>> class IFoo(zope.interface.Interface):
+ ... """Foo blah blah"""
+ ...
+ ... x = zope.interface.Attribute("""X blah blah""")
+ ...
+ ... def bar(q, r=None):
+ ... """bar blah blah"""
+
+ In the example above, we've created an interface, `IFoo`. We
+ subclassed `zope.interface.Interface`, which is an ancestor interface for
+ all interfaces, much as `object` is an ancestor of all new-style
+ classes [#create]_. The interface is not a class, it's an Interface,
+ an instance of `InterfaceClass`::
+
+ >>> type(IFoo)
+ <class 'zope.interface.interface.InterfaceClass'>
+
+ We can ask for the interface's documentation::
+
+ >>> IFoo.__doc__
+ 'Foo blah blah'
+
+ and its name::
+
+ >>> IFoo.__name__
+ 'IFoo'
+
+ As you can see, executable documentation is not just test code.
+ It's also a story which, just like all documentation, takes time and
+ effort to write. It is recommended to use first person plural
+ ("we") or second person ("you") in the story to involve the reader.
+ It also helps outlining use cases for the software, especially when
+ tests are written *before* the implementation ("test-driven
+ development").
+
+ Doctests should be valid reStructuredText and preferrably placed in
+ text files rather than in docstrings. The doctest files should be
+ named aptly so that developers can easily associate them with the
+ code in question, have the file extension ``.txt`` and are best
+ placed next to code in question.
+
+- **Other tests**, such as edge-case tests or bugfix tests. They too
+ need to be documented, but they usually have little value for
+ anybody seeking documentation on the software in question.
+
.. _doctests: http://docs.python.org/lib/module-doctest.html
More information about the Checkins
mailing list