Plone development: Nose or zope.testing ?

Python needs a better testing tool, hopefully this will happen some days.

Until then we, Plone developers use zope.testing for the best and the worst.
- the best because zope.testing provides layers and the Zope/Plone stack provides really nice things to work with them. - the worst because sometimes it just gives me some headaches to figure out how to set my test fixtures correctly. - the worst because I cannot easy-install zope.testing and just call it from the prompt to run some tests (this should get better sometimes see here)

That said, when you work with a zc.buildout based environment, it is easy to use zope.testing, thanks to zc.recipe.testrunner.

But since the eggification of Zope, we write more and more code that would benefit from a lighter test framework. Nose has this lighter approach, I love it to write simple tests without the Java-like heavy UnitTest framework. I can just write:
def test_something():

   assert 1 == 1

And call nosetests. Test fixtures are easy to set at all levels as well, using the with_setup decorator.

I tried to write some tests that could be launchable from both frameworks, by making some bridges, but I came up to the conclusion that a package should fully use either zope.testing, either Nose.

So now, I use two test scripts in my zc.buildout environments, and decide depending on the package. I have written another recipe for buildout to bind Nose: pbp.recipe.noserunner.

From there, I create two sections in my buildout.cfg file:
[buildout]

parts =

    ...

    nose

    ztest



[nose]

recipe = pbp.recipe.noserunner

eggs =

    egg1

    egg2



[ztest]

recipe = zc.recipe.testrunner

eggs =

    egg3

    egg4

These will generate two test scripts
- nose to run nosetests with egg1 and egg2 in sys.path - ztest to run zope.testing with egg3 and egg4 in sys.path

Here's my grid of choices when I am coding:
- zc.buildout recipes : zope.testing (doctests using zc.buildout testing framework) - Plone packages: zope.testing - Python packages and 'everything' else: Nose