Test fixture driven development for Plone add-ons?
You may have already seen Maurizio Delmonte’s demo of collective.cover, the new Tiles based front-page product for Plone. It’s based on the same technologies as Deco, but it actually delivers. Just amazing work from our South American Plone friends.
Here’s a new (developer) way to try out this wonderful product:
-
Download
bootstrap.py
$ curl -O http://downloads.buildout.org/2/bootstrap.py
-
Write
buildout.cfg
[buildout] extends = http://dist.plone.org/release/4.3-latest/versions.cfg versions = versions parts = robot [robot] recipe = zc.recipe.egg eggs = collective.cover[test] plone.app.robotframework [versions] # These versions are from collective.cover/versions.cfg collective.js.jqueryui = 1.10.1.2 plone.app.blocks = 1.0 plone.app.drafts = 1.0a2 plone.app.jquery = 1.7.2 plone.app.jquerytools = 1.5.5 plone.app.tiles = 1.0.1 plone.tiles = 1.2
-
Run the buildout
$ python bootstrap.py $ bin/buildout
-
Start the installed
bin/robot-server
with a specific functional test fixture shipped in collective.cover$ bin/robot-server collective.cover.testing.FUNCTIONAL_TESTING
-
Wait for
bin/robot-server
to start a volatile demo instance for you12:05:09 [ wait ] Starting Zope 2 server 12:05:41 [ ready ] Started Zope 2 server
-
Open browser at http://localhost:55001/plone/
-
Login with username
admin
and passwordsecret
, click Add new …-menu to add a new cover and have fun.
Wait… what just happened?
Meet the robot-server
robot-server is a test fixture based development server for Plone add-on development, and is currently shipped with plone.app.robotframework. It’s main function is to ease writing of Robot Framework tests for Plone, but it can be used as a more general development tool.
About a year ago, Godefroid Chapelle figured out that we could re-use Plone’s and its add-ons’ modern test fixtures (see plone.app.testing) to start a testable Plone sandbox directly from Robot Framework’s own test runner. Even better finding was that you could re-use the test fixtures to start a Plone sandbox in a way that you could ran multiple isolated Robot Framework test against it with running expensive setups and teardowns only once. This work was finished at the Barcelona Plone Testing Sprint in the last February.
To see better, how test fixtures are set up by robot-server, run it with
-v
for --verbose
:
$ bin/robot-server collective.cover.testing.FUNCTIONAL_TESTING -v
12:07:10 [ wait ] Starting Zope 2 server
12:07:10 [ wait ] Set up plone.testing.zca.LayerCleanup
12:07:10 [ wait ] Set up plone.testing.z2.Startup
12:07:10 [ wait ] Set up plone.app.testing.layers.PloneFixture
12:07:18 [ wait ] Set up collective.cover.testing.Fixture
12:07:25 [ wait ] Set up plone.testing.z2.ZServer
12:07:26 [ wait ] Set up collective.cover.testing.collective.cover:Functional
12:07:26 [ ready ] Started Zope 2 server
But that’s not all.
robot-server, reloaded
-
Write the following
develop.cfg
(on a Mac or Linux) next to the previousbuildout.cfg
[buildout] extends = buildout.cfg extensions = mr.developer auto-checkout = collective.cover [sources] collective.cover = git https://github.com/collective/collective.cover.git [robot] eggs += plone.app.robotframework[reload]
-
Run the buildout
$ bin/buildout -c develop.cfg
-
Start
bin/robot-server
$ bin/robot-server collective.cover.testing.FUNCTIONAL_TESTING -v 12:26:25 [ wait ] Starting Zope 2 server 12:26:25 [ wait ] Set up plone.testing.zca.LayerCleanup 12:26:25 [ wait ] Set up plone.testing.z2.Startup 12:26:25 [ wait ] Set up plone.app.testing.layers.PloneFixture 12:26:33 [ wait ] Watchdog is watching for changes in src 12:26:33 [ wait ] Fork loop now starting on parent process 98241 12:26:33 [ wait ] Fork loop forked a new child process 98244 12:26:33 [ wait ] Set up collective.cover.testing.Fixture 12:26:40 [ wait ] Set up plone.testing.z2.ZServer 12:26:41 [ wait ] Set up collective.cover.testing.collective.cover:Functional 12:26:41 [ ready ] Zope 2 server started
-
Edit a file under
src/collective/cover
and see how the sandbox is teared down toPLONE_FIXTURE
and all code for collective.cover is being reloaded12:27:49 [ wait ] Watchdog got modified event on collective.cover/src/collective/cover/config.py 12:27:49 [ wait ] Pruning Zope 2 server 12:27:49 [ wait ] Tear down collective.cover.testing.collective.cover:Functional 12:27:49 [ wait ] Tear down plone.testing.z2.ZServer 12:27:50 [ wait ] Tear down collective.cover.testing.Fixture 12:27:50 [ wait ] Fork loop terminated child process 98244 12:27:50 [ wait ] Fork loop forked a new child process 98536 12:27:50 [ wait ] Set up collective.cover.testing.Fixture 12:27:57 [ wait ] Set up plone.testing.z2.ZServer 12:27:58 [ wait ] Set up collective.cover.testing.collective.cover:Functional 12:27:58 [ ready ] Zope 2 server started
In short, when plone.app.robotframework is required with [reload]
it comes with a code reloading fork loop applied from
sauna.reload. It is not as
fast as the original, but this time it works for all add-ons. And it
does not only reload your code, but also re-builds your test fixture.
For example, all changes for add-on Generic Setup profile are applied
when the profile is configured in test fixture.
So, may be next time, when you start writing a new add-on for Plone, you
could start with writing a functional test fixture for it (see
plone.app.testing and include a z2.ZSERVER_FIXTURE) and give
robot-server
a spin.
Issues can be filed at GitHub. Thank you.