Tuesday, September 19, 2006

A work in progress chapter from Zope Guide

This is a work in progress chapter from Zope Guide:
http://kpug.zwiki.org/ZopeGuide
Please contribute! especially grammer mistakes :)


Unit testing
************


Introduction
------------

In this chapter, you will learn more about unit testing. Zope 3 use `doctest`
based unit testing heavily. Zope 3 preferes test driven development (TDD).

To explain the idea, consider a use case. A module is required with a function
which returns 'Good morning, name!'. The name will be given as argument.
Before writing the real code write the unit test for this. Infact you will be
writing the real code and it's test cases almost in parallel. So just create a
file named `example1.py` with just the function definition::

def goodmorning(name):
"This returns a good morning message"

See you are not yet wrote the logic yet. But this is necessary to run tests
successfully with failures!. Ok, now create a file named `example1.txt`
with test cases, use ReStructuredText format::

These are test for `example1` module.

First import the module::

>>> import example1

Now call the function `goodmorning` with out any argument::

>>> example1.goodmorning()
Traceback (most recent call last):
...
TypeError: goodmorning() takes exactly 1 argument (0 given)

Now call the function `goodmorning` with one argument::

>>> example1.goodmorning('Jack')
'Good morning, Jack!'

See the examples are written like executed from prompt. You can use your
python prompt and copy paste from there. Now create another file
`test_example1.py` with this content::

import unittest
import doctest

def test_suite():
return unittest.TestSuite((
doctest.DocFileSuite('example1.txt'),
))

if __name__ == '__main__':
unittest.main(defaultTest='test_suite')

This is just a boilerplate code for running the test. Now run the test using
`python2.4 test_example1.py` command.
You will get output with following text::

File "example1.txt", line 16, in example1.txt
Failed example:
example1.goodmorning('Jack')
Expected:
'Good morning, Jack!'
Got nothing

Now one test failed, so implement the function now::

def goodmorning(name):
"This returns a good morning message"
return "Good morning, %s!" % name

Now run the test again, it will run without failures.

Now start thinking about other functionalities required for the module. Before
start coding write about it in text file. Decide API, write test, write code,
than continue this cycle untill you finish your requirements.