[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