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

Last change on this file since 5828 was 5796, checked in by uli, 14 years ago

Brush up the main waeup.sirp unit test layer. It now groks waeup.sirp
if necessary only and cleans up the environment afterwards
properly. Also display of warning messages (all the erraneous messages
about missing templates and the like) is disabled now when grokking
waeup.sirp via the finetuned layer.

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