Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 415 lines (313 sloc) 16.08 kb
6408e13 @jean Whitespace.
jean authored
1 Integration tests
3575a9a @hvelarde nuke trailing whitespaces
hvelarde authored
2 =================
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
3
c9c1ecd @hvelarde replaced collective.testcaselayer with plone.app.testing
hvelarde authored
4 **Writing integration tests with plone.app.testing**
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
5
c432dd3 @jean Editing markup & formulation. Fixed some typos.
jean authored
6 We’ll now add some integration tests for our type.
7 These should ensure that the package installs cleanly, and that our custom
8 types are addable in the right places and have the right schemata, at the
9 very least.
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
10
11 To help manage test setup, we’ll make use of the Zope test runner’s
c432dd3 @jean Editing markup & formulation. Fixed some typos.
jean authored
12 concept of *layers*.
13 Layers allow common test setup (such as configuring a Plone site and
14 installing a product) to take place once and be re-used by multiple test
15 cases.
16 Those test cases can still modify the environment, but their changes will be
17 torn down and the environment reset to the layer’s initial state between
18 each test, facilitating test isolation.
19
20 As the name implies, layers are, erm, layered.
21 One layer can extend another.
22 If two test cases in the same test run use two different layers with a
23 common ancestral layer, the ancestral layer is only set up and torn down
24 once.
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
25
c9c1ecd @hvelarde replaced collective.testcaselayer with plone.app.testing
hvelarde authored
26 `plone.app.testing`_ provides tools for writing integration and functional
27 tests for code that runs on top of Plone, so we’ll use it.
28
29 In *setup.py*, we will add the extras_require option, like so:
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
30
31 ::
32
c9c1ecd @hvelarde replaced collective.testcaselayer with plone.app.testing
hvelarde authored
33 extras_require = {
34 'test': ['plone.app.testing']
35 },
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
36
37 .. note::
c432dd3 @jean Editing markup & formulation. Fixed some typos.
jean authored
38 Don’t forget to re-run buildout after making changes to ``setup.py``.
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
39
c432dd3 @jean Editing markup & formulation. Fixed some typos.
jean authored
40 `plone.app.testing`_ includes a set of layers that set up fixtures
41 containing a Plone site, intended for writing integration and functional
42 tests.
c9c1ecd @hvelarde replaced collective.testcaselayer with plone.app.testing
hvelarde authored
43
c432dd3 @jean Editing markup & formulation. Fixed some typos.
jean authored
44 We need to create a custom fixture.
45 The usual pattern is to create a new layer class that has ``PLONE_FIXTURE``
46 as its default base, instantiating that as a separate "fixture" layer.
47 This layer is not to be used in tests directly,
c9c1ecd @hvelarde replaced collective.testcaselayer with plone.app.testing
hvelarde authored
48 since it won't have test/transaction lifecycle management, but represents a
c432dd3 @jean Editing markup & formulation. Fixed some typos.
jean authored
49 shared fixture, potentially for both functional and integration testing.
50 It is also the point of extension for other layers that follow the same
51 pattern.
c9c1ecd @hvelarde replaced collective.testcaselayer with plone.app.testing
hvelarde authored
52
53 Once this fixture has been defined, "end-user" layers can be defined using the
54 IntegrationTesting and FunctionalTesting classes. We’ll add this in a
c432dd3 @jean Editing markup & formulation. Fixed some typos.
jean authored
55 ``testing.py`` file::
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
56
c9c1ecd @hvelarde replaced collective.testcaselayer with plone.app.testing
hvelarde authored
57 from plone.app.testing import PloneSandboxLayer
58 from plone.app.testing import PLONE_FIXTURE
59 from plone.app.testing import IntegrationTesting
60 from plone.app.testing import FunctionalTesting
61
62 class Fixture(PloneSandboxLayer):
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
63
c9c1ecd @hvelarde replaced collective.testcaselayer with plone.app.testing
hvelarde authored
64 defaultBases = (PLONE_FIXTURE,)
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
65
c9c1ecd @hvelarde replaced collective.testcaselayer with plone.app.testing
hvelarde authored
66 def setUpZope(self, app, configurationContext):
67 # Load ZCML
68 import example.conference
69 self.loadZCML(package=example.conference)
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
70
c9c1ecd @hvelarde replaced collective.testcaselayer with plone.app.testing
hvelarde authored
71 def setUpPloneSite(self, portal):
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
72 # Install the example.conference product
c9c1ecd @hvelarde replaced collective.testcaselayer with plone.app.testing
hvelarde authored
73 self.applyProfile(portal, 'example.conference:default')
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
74
c9c1ecd @hvelarde replaced collective.testcaselayer with plone.app.testing
hvelarde authored
75
76 FIXTURE = Fixture()
77 INTEGRATION_TESTING = IntegrationTesting(
78 bases=(FIXTURE,),
79 name='example.conference:Integration',
80 )
81 FUNCTIONAL_TESTING = FunctionalTesting(
82 bases=(FIXTURE,),
83 name='example.conference:Functional',
84 )
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
85
86 This extends a base layer that sets up Plone, and adds some custom layer
c432dd3 @jean Editing markup & formulation. Fixed some typos.
jean authored
87 setup for our package,
88 in this case installing the ``example.conference`` extension profile.
89 We could also perform additional setup here, such as creating some initial
90 content or setting the default roles for the test run.
91 See the *plone.app.testing* documentation for more details.
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
92
c432dd3 @jean Editing markup & formulation. Fixed some typos.
jean authored
93 To use the layer, we can create a new test case based on ``unittest.TestCase``
94 that uses our layer. We’ll add one to ``test_program.py`` first.
95 (In the code snippet below, the unit test we created previously has been
96 removed to conserve space.)
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
97
c9c1ecd @hvelarde replaced collective.testcaselayer with plone.app.testing
hvelarde authored
98 import unittest2 as unittest
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
99
100 from zope.component import createObject
101 from zope.component import queryUtility
102
c9c1ecd @hvelarde replaced collective.testcaselayer with plone.app.testing
hvelarde authored
103 from plone.app.testing import TEST_USER_ID
104 from plone.app.testing import setRoles
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
105
c9c1ecd @hvelarde replaced collective.testcaselayer with plone.app.testing
hvelarde authored
106 from plone.dexterity.interfaces import IDexterityFTI
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
107
108 from example.conference.program import IProgram
c9c1ecd @hvelarde replaced collective.testcaselayer with plone.app.testing
hvelarde authored
109 from example.conference.testing import INTEGRATION_TESTING
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
110
c9c1ecd @hvelarde replaced collective.testcaselayer with plone.app.testing
hvelarde authored
111 class TestProgramIntegration(unittest.TestCase):
3575a9a @hvelarde nuke trailing whitespaces
hvelarde authored
112
c9c1ecd @hvelarde replaced collective.testcaselayer with plone.app.testing
hvelarde authored
113 layer = INTEGRATION_TESTING
3575a9a @hvelarde nuke trailing whitespaces
hvelarde authored
114
f46a1e0 @hvelarde added setUp method to test modules
hvelarde authored
115 def setUp(self):
116 self.portal = self.layer['portal']
117 setRoles(self.portal, TEST_USER_ID, ['Manager'])
118 self.portal.invokeFactory('Folder', 'test-folder')
119 setRoles(self.portal, TEST_USER_ID, ['Member'])
120 self.folder = self.portal['test-folder']
121
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
122 def test_adding(self):
123 self.folder.invokeFactory('example.conference.program', 'program1')
124 p1 = self.folder['program1']
125 self.failUnless(IProgram.providedBy(p1))
3575a9a @hvelarde nuke trailing whitespaces
hvelarde authored
126
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
127 def test_fti(self):
128 fti = queryUtility(IDexterityFTI, name='example.conference.program')
129 self.assertNotEquals(None, fti)
3575a9a @hvelarde nuke trailing whitespaces
hvelarde authored
130
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
131 def test_schema(self):
132 fti = queryUtility(IDexterityFTI, name='example.conference.program')
133 schema = fti.lookupSchema()
134 self.assertEquals(IProgram, schema)
3575a9a @hvelarde nuke trailing whitespaces
hvelarde authored
135
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
136 def test_factory(self):
137 fti = queryUtility(IDexterityFTI, name='example.conference.program')
138 factory = fti.factory
139 new_object = createObject(factory)
140 self.failUnless(IProgram.providedBy(new_object))
3575a9a @hvelarde nuke trailing whitespaces
hvelarde authored
141
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
142 def test_view(self):
143 self.folder.invokeFactory('example.conference.program', 'program1')
144 p1 = self.folder['program1']
145 view = p1.restrictedTraverse('@@view')
146 sessions = view.sessions()
147 self.assertEquals(0, len(sessions))
3575a9a @hvelarde nuke trailing whitespaces
hvelarde authored
148
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
149 def test_start_end_dates_indexed(self):
150 self.folder.invokeFactory('example.conference.program', 'program1')
151 p1 = self.folder['program1']
152 p1.start = datetime.datetime(2009, 1, 1, 14, 01)
153 p1.end = datetime.datetime(2009, 1, 2, 15, 02)
154 p1.reindexObject()
3575a9a @hvelarde nuke trailing whitespaces
hvelarde authored
155
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
156 result = self.portal.portal_catalog(path='/'.join(p1.getPhysicalPath()))
3575a9a @hvelarde nuke trailing whitespaces
hvelarde authored
157
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
158 self.assertEquals(1, len(result))
159 self.assertEquals(result[0].start, DateTime('2009-01-01T14:01:00'))
160 self.assertEquals(result[0].end, DateTime('2009-01-02T15:02:00'))
3575a9a @hvelarde nuke trailing whitespaces
hvelarde authored
161
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
162 def test_tracks_indexed(self):
163 self.folder.invokeFactory('example.conference.program', 'program1')
164 p1 = self.folder['program1']
165 p1.tracks = ['Track 1', 'Track 2']
166 p1.reindexObject()
3575a9a @hvelarde nuke trailing whitespaces
hvelarde authored
167
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
168 result = self.portal.portal_catalog(Subject='Track 2')
3575a9a @hvelarde nuke trailing whitespaces
hvelarde authored
169
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
170 self.assertEquals(1, len(result))
171 self.assertEquals(result[0].getURL(), p1.absolute_url())
172
173 def test_suite():
174 return unittest.defaultTestLoader.loadTestsFromName(__name__)
175
176 This illustrates a basic set of tests that make sense for most content
c432dd3 @jean Editing markup & formulation. Fixed some typos.
jean authored
177 types.
178 There are many more things we could test
179 (for example, we could test the add permissions more thoroughly,
180 and we ought to test the ``sessions()`` method on the view with some actual
181 content!),
182 but even this small set of integration tests tells us that
183 our product has installed,
184 that the content type is addable,
185 that it has the right factory, and
186 that instances of the type provide the right schema interface.
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
187
188 There are some important things to note about this test case:
189
c432dd3 @jean Editing markup & formulation. Fixed some typos.
jean authored
190 - We extend ``unittest.TestCase``, which means we have access to a full Plone
191 integration test environment.
192 See the `testing tutorial`_ for more details.
193 - We set the ``layer`` attribute to our custom layer.
194 This means that all tests in our test case will have the
195 ``example.conference:default`` profile installed.
196 - We need to create a test user's member folder as self.folder because
197 ``plone.app.testing`` takes a minimalist approach and no content is available
198 by default.
199 - We test that the content is addable (here, as a normal member in
200 their member folder, since that is the default security context for
201 the test – use ``self.setRoles([‘Manager’])`` to get the ``Manager`` role
202 and ``self.portal`` to access the portal root),
203 that the FTI is installed and can be located, and
204 that both the FTI and instances of the type know about the correct type
205 schema.
206 - We also test that the view can be looked up and has the correct methods.
207 We’ve not included a fully functional test (e.g. using
208 ``zope.testbrowser``) or any other front-end testing here.
209 If you require those, take a look at the testing tutorial.
210 - We also test that our custom indexers are working,
211 by creating an appropriate object and searching for it.
212 Note that we need to reindex the object after we’ve modified it so that
213 the catalog is up to date.
214 - The ``defaultTestLoader`` will find this test and load it, just as it
215 found the ``TestProgramUnit`` test case.
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
216
217 To run our tests, we can still do.
218
c432dd3 @jean Editing markup & formulation. Fixed some typos.
jean authored
219 .. code-block:: console
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
220
221 $ ./bin/test example.conference
222
c432dd3 @jean Editing markup & formulation. Fixed some typos.
jean authored
223 You should now notice layers being set up and torn down.
224 Again, use the ``-t`` option to run a particular test case (or test method)
225 only.
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
226
c432dd3 @jean Editing markup & formulation. Fixed some typos.
jean authored
227 The other tests are similar. We have ``tests/test_session.py`` to test
228 the ``Session`` type::
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
229
c9c1ecd @hvelarde replaced collective.testcaselayer with plone.app.testing
hvelarde authored
230 import unittest2 as unittest
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
231
232 from zope.component import createObject
233 from zope.component import queryUtility
234
c9c1ecd @hvelarde replaced collective.testcaselayer with plone.app.testing
hvelarde authored
235 from plone.app.testing import TEST_USER_ID
236 from plone.app.testing import setRoles
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
237
c9c1ecd @hvelarde replaced collective.testcaselayer with plone.app.testing
hvelarde authored
238 from plone.dexterity.interfaces import IDexterityFTI
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
239
240 from example.conference.session import ISession
241 from example.conference.session import possible_tracks
c9c1ecd @hvelarde replaced collective.testcaselayer with plone.app.testing
hvelarde authored
242 from example.conference.testing import INTEGRATION_TESTING
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
243
c9c1ecd @hvelarde replaced collective.testcaselayer with plone.app.testing
hvelarde authored
244 class TestSessionIntegration(unittest.TestCase):
3575a9a @hvelarde nuke trailing whitespaces
hvelarde authored
245
c9c1ecd @hvelarde replaced collective.testcaselayer with plone.app.testing
hvelarde authored
246 layer = INTEGRATION_TESTING
3575a9a @hvelarde nuke trailing whitespaces
hvelarde authored
247
f46a1e0 @hvelarde added setUp method to test modules
hvelarde authored
248 def setUp(self):
249 self.portal = self.layer['portal']
250 setRoles(self.portal, TEST_USER_ID, ['Manager'])
251 self.portal.invokeFactory('Folder', 'test-folder')
252 setRoles(self.portal, TEST_USER_ID, ['Member'])
253 self.folder = self.portal['test-folder']
254
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
255 def test_adding(self):
3575a9a @hvelarde nuke trailing whitespaces
hvelarde authored
256
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
257 # We can't add this directly
258 self.assertRaises(ValueError, self.folder.invokeFactory, 'example.conference.session', 'session1')
3575a9a @hvelarde nuke trailing whitespaces
hvelarde authored
259
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
260 self.folder.invokeFactory('example.conference.program', 'program1')
261 p1 = self.folder['program1']
3575a9a @hvelarde nuke trailing whitespaces
hvelarde authored
262
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
263 p1.invokeFactory('example.conference.session', 'session1')
264 s1 = p1['session1']
265 self.failUnless(ISession.providedBy(s1))
3575a9a @hvelarde nuke trailing whitespaces
hvelarde authored
266
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
267 def test_fti(self):
268 fti = queryUtility(IDexterityFTI, name='example.conference.session')
269 self.assertNotEquals(None, fti)
3575a9a @hvelarde nuke trailing whitespaces
hvelarde authored
270
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
271 def test_schema(self):
272 fti = queryUtility(IDexterityFTI, name='example.conference.session')
273 schema = fti.lookupSchema()
274 self.assertEquals(ISession, schema)
3575a9a @hvelarde nuke trailing whitespaces
hvelarde authored
275
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
276 def test_factory(self):
277 fti = queryUtility(IDexterityFTI, name='example.conference.session')
278 factory = fti.factory
279 new_object = createObject(factory)
280 self.failUnless(ISession.providedBy(new_object))
3575a9a @hvelarde nuke trailing whitespaces
hvelarde authored
281
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
282 def test_tracks_vocabulary(self):
283 self.folder.invokeFactory('example.conference.program', 'program1')
284 p1 = self.folder['program1']
285 p1.tracks = ['T1', 'T2', 'T3']
3575a9a @hvelarde nuke trailing whitespaces
hvelarde authored
286
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
287 p1.invokeFactory('example.conference.session', 'session1')
288 s1 = p1['session1']
3575a9a @hvelarde nuke trailing whitespaces
hvelarde authored
289
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
290 vocab = possible_tracks(s1)
3575a9a @hvelarde nuke trailing whitespaces
hvelarde authored
291
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
292 self.assertEquals(['T1', 'T2', 'T3'], [t.value for t in vocab])
293 self.assertEquals(['T1', 'T2', 'T3'], [t.token for t in vocab])
3575a9a @hvelarde nuke trailing whitespaces
hvelarde authored
294
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
295 def test_catalog_index_metadata(self):
296 self.failUnless('track' in self.portal.portal_catalog.indexes())
297 self.failUnless('track' in self.portal.portal_catalog.schema())
3575a9a @hvelarde nuke trailing whitespaces
hvelarde authored
298
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
299 def test_workflow_installed(self):
300 self.folder.invokeFactory('example.conference.program', 'program1')
301 p1 = self.folder['program1']
3575a9a @hvelarde nuke trailing whitespaces
hvelarde authored
302
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
303 p1.invokeFactory('example.conference.session', 'session1')
304 s1 = p1['session1']
3575a9a @hvelarde nuke trailing whitespaces
hvelarde authored
305
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
306 chain = self.portal.portal_workflow.getChainFor(s1)
307 self.assertEquals(('example.conference.session_workflow',), chain)
308
309 def test_suite():
310 return unittest.defaultTestLoader.loadTestsFromName(__name__)
311
c432dd3 @jean Editing markup & formulation. Fixed some typos.
jean authored
312 Notice here how we test
313 that the ``Session`` type cannot be added directly to a folder, and
314 that it can be added inside a program.
315 We also add a test for the ``possible_tracks()`` vocabulary method,
316 as well as tests for the installation of the ``track`` index and metadata
317 column and the custom workflow::
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
318
c9c1ecd @hvelarde replaced collective.testcaselayer with plone.app.testing
hvelarde authored
319 import unittest2 as unittest
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
320
321 from zope.component import createObject
322 from zope.component import queryUtility
323
c9c1ecd @hvelarde replaced collective.testcaselayer with plone.app.testing
hvelarde authored
324 from plone.app.testing import TEST_USER_ID
325 from plone.app.testing import setRoles
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
326
c9c1ecd @hvelarde replaced collective.testcaselayer with plone.app.testing
hvelarde authored
327 from plone.dexterity.interfaces import IDexterityFTI
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
328
329 from example.conference.presenter import IPresenter
c9c1ecd @hvelarde replaced collective.testcaselayer with plone.app.testing
hvelarde authored
330 from example.conference.testing import INTEGRATION_TESTING
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
331
c9c1ecd @hvelarde replaced collective.testcaselayer with plone.app.testing
hvelarde authored
332 class TestPresenterIntegration(unittest.TestCase):
3575a9a @hvelarde nuke trailing whitespaces
hvelarde authored
333
c9c1ecd @hvelarde replaced collective.testcaselayer with plone.app.testing
hvelarde authored
334 layer = INTEGRATION_TESTING
3575a9a @hvelarde nuke trailing whitespaces
hvelarde authored
335
f46a1e0 @hvelarde added setUp method to test modules
hvelarde authored
336 def setUp(self):
337 self.portal = self.layer['portal']
338 setRoles(self.portal, TEST_USER_ID, ['Manager'])
339 self.portal.invokeFactory('Folder', 'test-folder')
340 setRoles(self.portal, TEST_USER_ID, ['Member'])
341 self.folder = self.portal['test-folder']
342
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
343 def test_adding(self):
344 self.folder.invokeFactory('example.conference.presenter', 'presenter1')
345 p1 = self.folder['presenter1']
346 self.failUnless(IPresenter.providedBy(p1))
3575a9a @hvelarde nuke trailing whitespaces
hvelarde authored
347
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
348 def test_fti(self):
349 fti = queryUtility(IDexterityFTI, name='example.conference.presenter')
350 self.assertNotEquals(None, fti)
3575a9a @hvelarde nuke trailing whitespaces
hvelarde authored
351
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
352 def test_schema(self):
353 fti = queryUtility(IDexterityFTI, name='example.conference.presenter')
354 schema = fti.lookupSchema()
355 self.assertEquals(IPresenter, schema)
3575a9a @hvelarde nuke trailing whitespaces
hvelarde authored
356
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
357 def test_factory(self):
358 fti = queryUtility(IDexterityFTI, name='example.conference.presenter')
359 factory = fti.factory
360 new_object = createObject(factory)
361 self.failUnless(IPresenter.providedBy(new_object))
3575a9a @hvelarde nuke trailing whitespaces
hvelarde authored
362
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
363 def test_suite():
364 return unittest.defaultTestLoader.loadTestsFromName(__name__)
365
366 Faster tests with Roadrunner
367 ----------------------------
368
c432dd3 @jean Editing markup & formulation. Fixed some typos.
jean authored
369 .. warning::
c9c1ecd @hvelarde replaced collective.testcaselayer with plone.app.testing
hvelarde authored
370 Roadrunner development halted in 2009. The following is only useful if you
371 are using Plone 3.x.
372
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
373 You will have noticed that running unit tests was much quicker than
374 running integration tests. That is unfortunate, but to be expected: the
375 integration test setup basically requires starting all of Zope and
376 configuring a Plone site.
377
378 Luckily, there is a tool that we can use to speed things up, and if
379 you’ve been following along the tutorial, you already have it in your
c432dd3 @jean Editing markup & formulation. Fixed some typos.
jean authored
380 buildout: `Roadrunner`_.
381 This is a command that takes the place of ``./bin/instance test`` that
382 preloads the Zope environment and allows you to re-run tests much faster.
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
383
384 To run our tests with roadrunner, we would do:
385
c432dd3 @jean Editing markup & formulation. Fixed some typos.
jean authored
386 .. code-block:: console
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
387
388 $ ./bin/roadrunner -s example.conference
389
390 This runs the tests once, and then drops to the Roadrunner prompt:
391
c432dd3 @jean Editing markup & formulation. Fixed some typos.
jean authored
392 .. code-block:: console
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
393
394 rr>
395
c432dd3 @jean Editing markup & formulation. Fixed some typos.
jean authored
396 Simply hitting enter here, or typing a command like
397 ``test -s example.conference`` will re-run your tests,
398 this time taking much less time.
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
399
c432dd3 @jean Editing markup & formulation. Fixed some typos.
jean authored
400 Roadrunner works best when you are adding and debugging your tests.
401 For example, it’s a very quick way to get to a ``pdb`` prompt: just set a
402 breakpoint in your test with ``import pdb; pdb.set_trace()`` and re-run
403 it in roadrunner.
404 You can then step into your test code and the code under test.
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
405
406 Roadrunner should pick up changes to your tests automatically. However,
407 it may not pick up changes to your application code, grokked components
408 or ZCML files. If it doesn’t, you’ll need to exit the Roadrunner prompt
409 and restart.
410
c432dd3 @jean Editing markup & formulation. Fixed some typos.
jean authored
411 .. _collective.testcaselayer: http://pypi.python.org/pypi/collective.testcaselayer
412 .. _plone.app.testing: http://pypi.python.org/pypi/plone.app.testing
52ab700 @giacomos Added sphinx-ified Dexterity Developer Manual
giacomos authored
413 .. _Roadrunner: http://pypi.python.org/pypi/roadrunner
414 .. _testing tutorial: /documentation/tutorial/testing
Something went wrong with that request. Please try again.