Martijn Faassen <faassen@vet.uu.nl>
Hi there,
Recently I've been reading some books [1] which put emphasis on the idea of unit testing. At the Python conference Joel Shprentz held a short talk about doing unit tests in Python [2]
Basically a unit tests are some simple test functions that are associated with a unit of code (a python module). The tests exercise the code in the module, and either succeed or fail (there may also be an error due to an uncaught exception). Each time you change something in the module you run the associated tests. The idea is that this makes debugging easier, catching bugs more quickly and giving better diagnostics. Doing unit tests in Python isn't hard to do.
I'm having more trouble thinking of a good way to do unit tests in Zope, though. Partially this is because Zope has various parts (the management interface for folders, ZClasses, product development), which each may need a different testing strategy. Partially this is because Zope currently mixes model and view together (though there are thoughts to do something about this [3]) -- unit tests are about testing code (methods and such), not user interfaces. Another problem is that much Zope code is not easy to test in isolation from Zope. Too much of the code depends on various Zope facilities (base classes, object database integration).
Has anybody any ideas on how to do unit testing within the Zope framework? I'd like to try adopting somekind of unit test strategy for my Zope development.
I got addicted to unit testing after reading John Lakos' excellent book, _Large Scale C++ Software Design_. He emphasises not only unit tests, but a more elaborate strategy, "design for testability:" not only does each module come with its own tests, but the system knows about dependencies between modules, and guarantees to test the depended-on modules before their dependents (so as to avoid spurious errors). In the Zope world, I think this has to translate to somthing like: 1. Each Python module should have a set of associated tests, which would by preference live inside the "if __name__ == '__main__'" block at the bottom of the module (an alternative would be to use Tim Peters' DocTest stuff, which embeds the unit tests in docstrings). One would then have a script, like the one which compiles all the Python modules during installation, to run these modules (perhaps using some fancy dependency analysis based on the import statements?) 2. For testing ZClasses, I am afraid that some kind of ZClient-based test will be required. Each test would: * Generate a suitably-unique folder name. * Construct a folder of that name off the root of the ZODB. * Build all scaffolding objects inside the new folder. * Run the tests, capturing the results and comparing them against expectations. * Finally, blow away the sandbox folder. Perhaps, as you point out, some of the effort to disentangle the core Python model from the HTML view will make such testing easier to lay down in the Zope core itself. Given a suitable framework, product developers could even allow third parties to contribute tests highlighting bugs they have found.
[1] Martin Fowler, ed., Refactoring: Improving the Design of Existing Code, Addison Wesley Longman, 1999
This is the best book I have read on the actual practice of "Extreme Programming" -- I recommend it highly.
Kent Beck, Extreme Programming Explained, Addison Wesley Longman, 1999
This book is a somewhat higher-level view of XP, and an "apologetic" for it (in the old, technical sense). Still quite useful to read, but not as much meat for the working programmer to digest.
[2] http://www.python.org/workshops/2000-01/proceedings/posters/shprentz/shprent... http://c2.com/cgi/wiki?PythonUnit
I have put up the code I currently use for unit testing Python modules at: http://www.zope.org/Members/tseaver/PyUnit
[3] http://www.zope.org/Resources/Mozilla/ZWiki/ZopeMVC http://www.zope.org/Resources/Mozilla/ZWiki/ModelViewController
-- ========================================================= Tres Seaver tseaver@palladion.com 713-523-6582 Palladion Software http://www.palladion.com