source: main/waeup.sirp/trunk/src/waeup/sirp/testing.py @ 5891

Last change on this file since 5891 was 5865, checked in by uli, 14 years ago

Make the zope.Public permission available during regular unittests.

This permission is normally registered during ZCML parsing at startup,
but we cannot grok components with that requirement set in normal
unittests, as they simply perform no ZCML parsing at start.

With defining zope.Public we can also grok waeup.sirp in unittests and
define components that require that permission.

  • Property svn:eol-style set to native
File size: 5.6 KB
Line 
1"""Testing support for :mod:`waeup.sirp`.
2"""
3import os.path
4import warnings
5import grok
6import zope.component
7import waeup.sirp
8from zope.app.testing.functional import ZCMLLayer
9from zope.component import getGlobalSiteManager
10from zope.security.testing import addCheckerPublic
11from zope.testing.cleanup import cleanUp
12
13ftesting_zcml = os.path.join(
14    os.path.dirname(waeup.sirp.__file__), 'ftesting.zcml')
15FunctionalLayer = ZCMLLayer(ftesting_zcml, __name__, 'FunctionalLayer',
16                            allow_teardown=True)
17
18def setUpZope(test=None):
19    """Initialize a Zope-compatible environment.
20
21    Currently, we only initialize the event machinery.
22    """
23    zope.component.eventtesting.setUp(test)
24
25def cleanUpZope(test=None):
26    """Clean up Zope-related registrations.
27
28    Cleans up all registrations and the like.
29    """
30    cleanUp()
31
32def maybe_grok():
33    """Try to grok the :mod:`waeup.sirp` package.
34
35    For many tests, even simple ones, we want the components defined
36    somewhere in the :mod:`waeup.sirp` package being registered. While
37    grokking the complete package can become expensive when done many
38    times, we only want to grok if it did not happen
39    before. Furthermore regrokking the whole package makes no sense if
40    done already.
41
42    :func:`maybe_grok` checks whether any eventhandlers are already
43    registered and does nothing in that case.
44
45    The grokking of :mod:`waeup.sirp` is done with warnings disabled.
46
47    Returns ``True`` if grokking was done, ``False`` else.
48
49    .. The following samples should go into Sphinx docs directly....
50   
51    Sample
52    ******
53
54    Usage with plain Python testrunners
55    -----------------------------------
56   
57    Together with the :func:`setUpZope` and :func:`cleanUpZope`
58    functions we then can do unittests with all components registered
59    and the event dispatcher in place like this::
60
61      import unittest2 as unittest # Want Python 2.7 features
62      from waeup.sirp.testing import (
63        maybe_grok, setUpZope, cleanUpZope,
64        )
65      from waeup.sirp.app import University
66
67      class MyTestCase(unittest.TestCase):
68
69          @classmethod
70          def setUpClass(cls):
71              grokked = maybe_grok()
72              if grokked:
73                  setUpZope(None)
74              return
75
76          @classmethod
77          def tearDownClass(cls):
78              cleanUpZope(None)
79
80          def setUp(self):
81              pass
82       
83          def tearDown(self):
84              pass
85
86          def test_jambdata_in_site(self):
87              u = University()
88              self.assertTrue('jambdata' in u.keys())
89              return
90
91    Here the component registration is done only once for the whole
92    :class:`unittest.TestCase` and no ZODB is needed. That means
93    inside the tests you can expect to have all :mod:`waeup.sirp`
94    components (utilities, adapter, events) registered but as objects
95    have here still have no place inside a ZODB things like 'browsing'
96    won't work out of the box. The benefit is the faster test
97    setup/teardown.
98
99    .. note:: This works only with the default Python testrunners.
100   
101         If you use the Zope testrunner (from :mod:`zope.testing`)
102         then you have to use appropriate layers like the
103         :class:`waeup.sirp.testing.WAeUPSIRPUnitTestLayer`.
104
105    Usage with :mod:`zope.testing` testrunners
106    ------------------------------------------
107
108    If you use the standard Zope testrunner, classmethods like
109    `setUpClass` are not executed. Instead you have to use a layer
110    like the one defined in this module.
111
112    .. seealso:: :class:`waeup.sirp.testing.WAeUPSIRPUnitTestLayer`
113   
114    """
115    gsm =  getGlobalSiteManager()
116    # If there are any event handlers registered already, we assume
117    # that waeup.sirp was grokked already. There might be a batter
118    # check, though.
119    if len(list(gsm.registeredHandlers())) > 0:
120        return False
121    # Register the zope.Public permission, normally done via ZCML setup.
122    addCheckerPublic()
123    warnings.simplefilter('ignore') # disable (erraneous) warnings
124    grok.testing.grok('waeup.sirp')
125    warnings.simplefilter('default') # reenable warnings
126    return True
127
128
129class WAeUPSIRPUnitTestLayer(object):
130    """A layer for tests that groks `waeup.sirp`.
131
132    A Zope test layer that registers all :mod:`waeup.sirp` components
133    before attached tests are run and cleans this registrations up
134    afterwards. Also basic (non-waeup.sirp) components like the event
135    dispatcher machinery are registered, set up and cleaned up.
136
137    This layer does not provide a complete ZODB setup (and is
138    therefore much faster than complete functional setups) but does
139    only the registrations (which also takes some time, so running
140    this layer is slower than test cases that need none or only a
141    few registrations).
142
143    The registrations are done for all tests the layer is attached to
144    once before all these tests are run (and torn down once
145    afterwards).
146   
147    To make use of this layer, you have to write a
148    :mod:`unittest.TestCase` class that provides an attribute called
149    ``layer`` with this class as value like this::
150
151      import unittest
152      from waeup.sirp.testing import WAeUPSIRPUnitTestLayer
153     
154      class MyTestCase(unittest.TestCase):
155
156          layer = WAeUPSIRPUnitTestLayer
157
158          # per-test setups and real tests go here...
159          def test_foo(self):
160              self.assertEqual(1, 1)
161              return
162
163    """
164    @classmethod
165    def setUp(cls):
166        #setUpZope(None)
167        grokked = maybe_grok()
168        if grokked:
169            pass
170            #setUpZope(None)
171        return
172
173    @classmethod
174    def tearDown(cls):
175        cleanUpZope(None)
Note: See TracBrowser for help on using the repository browser.