Plone TestCase integration with Windmill testing
Project description
About
niteoweb.windmill extends Plone’s FunctionalTestCase to provide support for running Windmill tests. This is achieved by adding an additional test layer, which starts a single-threaded ZServer instance alongside the Windmill server.
Windmill supports most of modern browser. The controller API can be found at http://trac.getwindmill.com/wiki/ControllerApi.
For more details, see http://getwindmill.com
Remember to read source code, it’s very lightweight!
Accessing the Windmill client
Windmill tests should derive from WindmillTestCase. This provides an instance of WindmillClient as self.wm. In addition to supporting the standard WindMillClient API, this client has an extra method open_site(), which automatically prepends the Plone site URL when opening a URL. It is otherwise identical to the open() method.
FAQ
How do I synchronize data manipulated by actions in browser and unittests:
In Windmill TestCase, self.site_open() always calls transaction.commit() which writes data to ZODB.
In unittests, just do import transaction;transaction.commit() and data will be seen in browser.
Installation
Add niteoweb.windmill as a dependency of the package that uses it in setup.py. One way to do that is via a [tests] extra, e.g.:
extras_require = { 'tests': ['niteoweb.windmill'], },
You then add this to your buildout, e.g.:
[tests] recipe = zc.recipe.testrunner eggs = my.package [tests]
Usage
Basic usage:
from Products.PloneTestCase import PloneTestCase as ptc from niteoweb.windmill import WindmillTestCase ptc.setupPloneSite() class TestSample(WindmillTestCase): def afterSetUp(self): self.setRoles(['Manager']) self.login_user() def test_foo(self): self.wm.open_site(url="/about") self.wm.waits.forPageLoad(timeout=30000) def test_suite(): from unittest import TestSuite, makeSuite suite = TestSuite() suite.addTest(makeSuite(TestSample)) return suite
Advanced usage:
from Products.PloneTestCase import PloneTestCase as ptc from niteoweb.windmill import WindmillTestCase, WindmillLayer class CustomWindmillLayer(WindmillLayer): site = 'plone2' windmill_settings = WindmillLayer.windmill_settings.copy() windmill_settings['START_FIREFOX'] = False WindmillLayer.windmill_settings['START_CHROME'] = True ptc.setupPloneSite() class TestWM(WindmillTestCase): layer = CustomWindmillLayer def afterSetUp(self): self.setRoles(['Manager']) self.login_user() def test_foo(self): self.wm.open_site('/login_form', site='plone2') self.wm.waits.forPageLoad(timeout=30000) def test_suite(): from unittest import TestSuite, makeSuite suite = TestSuite() suite.addTest(makeSuite(TestWM)) return suite
and run tests with debug mode to stop on error/failure:
bin/instance test -s package.module -t test_foo -D
Known issues
On teardown, you sometimes will get AttributeError: ‘NoneType’ object has no attribute ‘exc_info’. Ignore it
Windmill is very poorly tested on Python2.4, submit bugs if you stumble upon any;)
TODO
Some simple integration to load existing ZODB storages
CHANGELOG
0.3.2 (2011-09-15)
Changed the way, the test setup waits for the zserver to finish. This helps with timing issues that manifest in quite weird and misleading error messages. [do3cc]
0.3.1 (09.05.2010)
use portal_owner instead of default_user for better compatibility with loginAsPortalOwner() [Domen Kozar]
0.3 (12.12.2009)
Refactor to start ZServer in a separate layer rather than use startZServer() from ZopeTestCase. This is more reliable in case of other tests in the same test run that may require a running ZServer, because startZServer() is not layer aware and cannot be reliably torn down. [Martin Aspeli]
0.2 (23.11.2009)
added self.add_user function to testcase (be able to add users with custom roles) [Domen Kozar]
fixed first request failing (due to windmill/plone racecodintions) [Martin Aspeli]
fixed windmill dependency pulling [Martin Aspeli]
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.