"""Testing support for :mod:`waeup.sirp`. """ import os.path import warnings import grok import zope.component import waeup.sirp from zope.app.testing.functional import ZCMLLayer from zope.component import getGlobalSiteManager from zope.security.testing import addCheckerPublic from zope.testing.cleanup import cleanUp ftesting_zcml = os.path.join( os.path.dirname(waeup.sirp.__file__), 'ftesting.zcml') FunctionalLayer = ZCMLLayer(ftesting_zcml, __name__, 'FunctionalLayer', allow_teardown=True) def setUpZope(test=None): """Initialize a Zope-compatible environment. Currently, we only initialize the event machinery. """ zope.component.eventtesting.setUp(test) def cleanUpZope(test=None): """Clean up Zope-related registrations. Cleans up all registrations and the like. """ cleanUp() def maybe_grok(): """Try to grok the :mod:`waeup.sirp` package. For many tests, even simple ones, we want the components defined somewhere in the :mod:`waeup.sirp` package being registered. While grokking the complete package can become expensive when done many times, we only want to grok if it did not happen before. Furthermore regrokking the whole package makes no sense if done already. :func:`maybe_grok` checks whether any eventhandlers are already registered and does nothing in that case. The grokking of :mod:`waeup.sirp` is done with warnings disabled. Returns ``True`` if grokking was done, ``False`` else. .. The following samples should go into Sphinx docs directly.... Sample ****** Usage with plain Python testrunners ----------------------------------- Together with the :func:`setUpZope` and :func:`cleanUpZope` functions we then can do unittests with all components registered and the event dispatcher in place like this:: import unittest2 as unittest # Want Python 2.7 features from waeup.sirp.testing import ( maybe_grok, setUpZope, cleanUpZope, ) from waeup.sirp.app import University class MyTestCase(unittest.TestCase): @classmethod def setUpClass(cls): grokked = maybe_grok() if grokked: setUpZope(None) return @classmethod def tearDownClass(cls): cleanUpZope(None) def setUp(self): pass def tearDown(self): pass def test_jambdata_in_site(self): u = University() self.assertTrue('jambdata' in u.keys()) return Here the component registration is done only once for the whole :class:`unittest.TestCase` and no ZODB is needed. That means inside the tests you can expect to have all :mod:`waeup.sirp` components (utilities, adapter, events) registered but as objects have here still have no place inside a ZODB things like 'browsing' won't work out of the box. The benefit is the faster test setup/teardown. .. note:: This works only with the default Python testrunners. If you use the Zope testrunner (from :mod:`zope.testing`) then you have to use appropriate layers like the :class:`waeup.sirp.testing.WAeUPSIRPUnitTestLayer`. Usage with :mod:`zope.testing` testrunners ------------------------------------------ If you use the standard Zope testrunner, classmethods like `setUpClass` are not executed. Instead you have to use a layer like the one defined in this module. .. seealso:: :class:`waeup.sirp.testing.WAeUPSIRPUnitTestLayer` """ gsm = getGlobalSiteManager() # If there are any event handlers registered already, we assume # that waeup.sirp was grokked already. There might be a batter # check, though. if len(list(gsm.registeredHandlers())) > 0: return False # Register the zope.Public permission, normally done via ZCML setup. addCheckerPublic() warnings.simplefilter('ignore') # disable (erraneous) warnings grok.testing.grok('waeup.sirp') warnings.simplefilter('default') # reenable warnings return True class WAeUPSIRPUnitTestLayer(object): """A layer for tests that groks `waeup.sirp`. A Zope test layer that registers all :mod:`waeup.sirp` components before attached tests are run and cleans this registrations up afterwards. Also basic (non-waeup.sirp) components like the event dispatcher machinery are registered, set up and cleaned up. This layer does not provide a complete ZODB setup (and is therefore much faster than complete functional setups) but does only the registrations (which also takes some time, so running this layer is slower than test cases that need none or only a few registrations). The registrations are done for all tests the layer is attached to once before all these tests are run (and torn down once afterwards). To make use of this layer, you have to write a :mod:`unittest.TestCase` class that provides an attribute called ``layer`` with this class as value like this:: import unittest from waeup.sirp.testing import WAeUPSIRPUnitTestLayer class MyTestCase(unittest.TestCase): layer = WAeUPSIRPUnitTestLayer # per-test setups and real tests go here... def test_foo(self): self.assertEqual(1, 1) return """ @classmethod def setUp(cls): #setUpZope(None) grokked = maybe_grok() if grokked: pass #setUpZope(None) return @classmethod def tearDown(cls): cleanUpZope(None)