At The Health Agency we’re currently
switching to z3c.testsetup for
our test setup needs. The nice thing is that you only need one test .py file
that is found by your testrunner (I suggest tests/test_setup.py) with the
following content:

No more manual building of test suites with DocTestCases and so. Just add
:doctest: to every README or .txt or docstring-in-your.py like this:

..:doctest:>>>print44

For testing our libraries, simple python-level doctests are often enough.
From time to time you need to call grokcore.component.grok('my.package')
but that’s about it. The base package for our grok sites needs a more
elaborate setup. And preferably a setup that is reusable in the grok sites
that use it.

Solution for more elaborate test setups: test layers. Zope.testing
provides a layer mechanism. It took me some time to understand their use, but
I think I’ve got it:

You can tie a test to a layer. All tests that “are on the same layer” are
run in one group.

The layer can do setup before and after the layer’s tests are run. This
means a layer is useful for setting up your zodb; an test sql database; some
zcml setup.

The layer can also do extra layer-specific setup/teardown for every
individual test inside it. A layer that provides a zodb can thus arrange
for a transaction.abort() to be done after every single test: test
isolation.

After an all-important fromzope.app.testing.functionalimportFunctionalTestSetup, what my layer does is:

In the setUp(), instantiate FunctionalTestSetup with our own ftesting.zcml.

In the setUp(), grok a fixtures.py with a test site object, some test
user folders, test adapters and so. This makes those grokked components
available to every test on this layer.

testSetUp() is the setup method that is called for every individual test.
It calls FunctionalTestSetup’s setup that gives us a fresh clean ZODB. And
it sets up a test grok site (of our own design) in the ZODB’s root.

On both levels there’s the corresponding tear down method.

Using layers is easy with z3c.testsetup: add a :layer:my.package.layer.

One z3c.testsetup gotcha: it internally creates testcases, so it is hard to
pass in globals to the testcase (unless you do it in one go for all the tests
in the entire package, which wasn’t appropriate). The solution: call a setup
method by adding :setup:my.package.globsetup to your doctest.
globsetup(test) can append to the test.globs dictionary. I found it a
bit dirty at first, but after using it for a while it smells OK. You set the
globs explicitly in those doctests where you need it. In every doctest, it is
clear which extra setup methods are called and thus it is easy to look up that
method to see which globals are available.

An alternative to this setup call is of course to do an frommy.package.globsimport* or something like that. Which seems a bit
cleaner. Time for some experimentation. Oh, if someone knows how to set the
globs from within a layer: please mail me.

Comment by Jasper: grok < 1.0a4 contain z3c.testsetup 0.2.1, so make sure you
pin it to a more recent release like 0.4.