[Zope3-dev] Mail delivery failed: returning message to sender
Mail Delivery System
Mailer-Daemon at python.org
Tue Feb 17 07:51:36 EST 2004
This message was created automatically by mail delivery software.
A message that you sent could not be delivered to one or more of its
recipients. This is a permanent error. The following address(es) failed:
corey at streamreel.net
SMTP error from remote mailer after RCPT TO:<corey at streamreel.net>:
host iris1.directnic.com [204.251.10.81]: 550 5.7.1 No such recipient
------ This is a copy of the message, including all the headers. ------
Return-path: <zope3-dev at zope.org>
Received: from cache1.zope.org ([12.155.117.38])
by mail.python.org with esmtp (Exim 4.22)
id 1At4ge-0007E8-D5; Tue, 17 Feb 2004 07:50:52 -0500
From: zope3-dev at zope.org (srichter)
Reply-To: zope3-dev at zope.org
To: ;
Subject: [DocTests] (new) first draft (generated from LaTeX file)
Message-ID: <20040217075052EST at dev.zope.org>
X-BeenThere: zope3-dev at zope.org
X-Zwiki-Version: 0.21.1
Precedence: bulk
List-Id: <zope3-dev at zope.org>
List-Post: <mailto:zope3-dev at zope.org>
List-Subscribe: <http://dev.zope.org/Wikis/DevSite/Projects/ComponentArchitecture/DocTests/subscribeform>
List-Unsubscribe: <http://dev.zope.org/Wikis/DevSite/Projects/ComponentArchitecture/DocTests/subscribeform>
List-Archive: <http://dev.zope.org/Wikis/DevSite/Projects/ComponentArchitecture/DocTests>
List-Help: <http://dev.zope.org/Wikis/DevSite/Projects/ComponentArchitecture>
Date: Tue, 17 Feb 2004 07:50:52 -0500
X-Spam-Status: OK (default 0.000)
Doctests: Example-driven Unit Tests
Status
IsDraft
Authors
StephanRichter
Difficulty
Newcomer Level
Skills
- You should have read the previous recipe on unit tests, since
this recipe heavily depends on it.
Problem/Task
Unit tests are nice, but they are not the best implementation of
what eXtreme Programming expects of testing. Testing should also serve as
documentation, a requirement that the conventional unit test module
pattern does not provide. This recipe will show you an alternative way of
writing unit tests that can also serve well as documentation.
Recipe
Introduction
Python already provides doc strings for classes and methods, which
serve - like the name suggests - as documentation for the object. If you
would be able to write tests in the doc strings of classes and methods
and execute them during test runs, all requirements are fulfilled. Even
better, the tests would automatically become part of the documentation.
This way the documentation reader would always see a working example of
the code. Since most people learn by example, this will also speed up the
learning process of the technology.
The solution to this problem are doc tests, which have exactely the
described behavior. If you embed Python-prompt-like sample code in the
doc strings of a class and register the contained module as one having
doc tests, then the Python code in the doc strings is executed for
testing. Each doc string will be counted as a single test.
Integrating the Doc Test
So how does our example change from the previous recipe? First of
all, you can completely get rid of the 'TestSample' class. Next, add
the following lines to the doc string of the 'Sample' class::
01 Examples::
03 >>> sample = Sample()
05 Here you can see how the 'title' attribute works.
07 >>> print sample.title
08 None
09 >>> sample.title = 'Title'
10 >>> print sample.title
11 Title
13 The description is implemented using a accessor and mutator method
15 >>> sample.getDescription()
16 ''
17 >>> sample.setDescription('Hello World')
18 >>> sample.getDescription()
19 'Hello World'
20 >>> sample.setDescription(u'Hello World')
21 >>> sample.getDescription()
22 u'Hello World'
24 'setDescription()' only accepts regular and unicode strings
26 >>> sample.setDescription(None)
27 Traceback (most recent call last):
28 File "<stdin>", line 1, in ?
29 File "test_sample.py", line 31, in setDescription
30 assert isinstance(value, (str, unicode))
31 AssertionError
o Line 1: The double colon at this line is not mistake. In Zope
3's documentation tools we assume that all doc strings are written in
structured text, a plain text format that allows to insert some markup
without destroying the readability of the text. The double colon simply
signifies the beginning of a code segment.
o Line 5, 13 & 24: It is even possible to insert additional
comments for better documentation.
Before we can run the tests, we have to change the way the tests are
executed. The last two lines should now read::
01 if __name__ == '__main__':
02 unittest.main(defaultTest='test_suite')
You can now execute the test as before using 'Python test' . As you
can see doc tests are a much more natural way to test your code. However,
there are a couple of issues that one should be aware of when using doc
tests.
Shortcomings
The most obvious problem is that if you like to test attributes and
properties, there is no doc string to place the tests. This problem is
usually solved by testing attributes implicitely in context of other
tests and/or place their tests in the class' doc string. This solution is
actually good, since attributes by themselves usually do not have much
functionality, but are used in combination with methods to provide
functionality.
Next, it is not easy for certain outputs. The prime example here is
'None' , since it has no representation. The easy way around this is
to make the testing statement a condition. So the statement 'methodReturningNone()'
which should return 'None' is converted to 'methodReturningNone() is None'
which should return 'True' . There are also some issues when testing
statements that return output whose representation is longer than a line,
since the doc string checker is not smart enough the remove the
indentation white space. A good example of such objects are lists and
tuples. The easy solution is to save the list and only test some chunks
at a time.
Over time I have noticed that using doc tests makes me write sloppy
tests. Since I think of the tests as examples to show how the class is
supposed to work, I often neglect to test for all aspects and possible
situation a piece of code could come into. This problem can be solved by
either writing some additional classic unit tests or create a special
testing module that contains further doc tests.
While doc tests cover 98%of all test situations well, there are
some tests that require heavy programming. A good example of that is a
test in the internationalization support that makes sure that all XML
locale files can be parsed and some of the most important data is
correctly evaluated. I found that it is totally okay to use regular unit
tests for these scenarios.
Overall I think doc tests are the way to go!
Exercises
- Exercise 1: As a matter of taste, some people like it better
when each method is tested in the method doc string. Therefore, move
the 'getDescription' and 'setDescription' tests to the methods
doc string and make sure that all three tests pass.
- Exercise 2: Once you have split up the tests, you always have to
setup the 'sample' object over and over again. Here doc tests
also provide a way to specify a 'setUp()' and 'tearDown()'
method. They can be passed in as the second and third argument of the 'DocTestSuite'
, respectively. Change the tests in a way that they use a 'setUp()'
method for creating the 'Sample' instance.
- Exercise 3: (Equivalent to excercise 2 in the previous recipe)
Currently the 'test' test only verifies that None is not allowed
as input value.
- Improve the test, so that all other builtin types are tested
as well.
- Also, make sure that any objects inheriting from 'str' or 'unicode'
pass as valid values.
--
forwarded from http://dev.zope.org/Wikis/DevSite/Projects/ComponentArchitecture/DocTests
More information about the Zope3-dev
mailing list