~landscape/zope3/ztk-1.1.3

« back to all changes in this revision

Viewing changes to src/zope/testing/testrunner/testrunner-layers-api.txt

  • Committer: Thomas Hervé
  • Date: 2009-09-21 06:45:37 UTC
  • mfrom: (7.1.2 newer-zope-testing)
  • Revision ID: thomas@canonical.com-20090921064537-zcfyuv32hxj9eah0
Merge newer-zope-testing [a=sidnei] [f=429702] [r=therve,free.ekayanaka]

Update zope.testing to 3.8.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
Layers
 
2
======
 
3
 
 
4
A Layer is an object providing setup and teardown methods used to setup
 
5
and teardown the environment provided by the layer. It may also provide
 
6
setup and teardown methods used to reset the environment provided by the
 
7
layer between each test.
 
8
 
 
9
Layers are generally implemented as classes using class methods.
 
10
 
 
11
>>> class BaseLayer:
 
12
...     def setUp(cls):
 
13
...         log('BaseLayer.setUp')
 
14
...     setUp = classmethod(setUp)
 
15
...
 
16
...     def tearDown(cls):
 
17
...         log('BaseLayer.tearDown')
 
18
...     tearDown = classmethod(tearDown)
 
19
...
 
20
...     def testSetUp(cls):
 
21
...         log('BaseLayer.testSetUp')
 
22
...     testSetUp = classmethod(testSetUp)
 
23
...
 
24
...     def testTearDown(cls):
 
25
...         log('BaseLayer.testTearDown')
 
26
...     testTearDown = classmethod(testTearDown)
 
27
...
 
28
 
 
29
Layers can extend other layers. Note that they do not explicitly
 
30
invoke the setup and teardown methods of other layers - the test runner
 
31
does this for us in order to minimize the number of invocations.
 
32
 
 
33
>>> class TopLayer(BaseLayer):
 
34
...     def setUp(cls):
 
35
...         log('TopLayer.setUp')
 
36
...     setUp = classmethod(setUp)
 
37
...
 
38
...     def tearDown(cls):
 
39
...         log('TopLayer.tearDown')
 
40
...     tearDown = classmethod(tearDown)
 
41
...
 
42
...     def testSetUp(cls):
 
43
...         log('TopLayer.testSetUp')
 
44
...     testSetUp = classmethod(testSetUp)
 
45
...
 
46
...     def testTearDown(cls):
 
47
...         log('TopLayer.testTearDown')
 
48
...     testTearDown = classmethod(testTearDown)
 
49
...
 
50
 
 
51
Tests or test suites specify what layer they need by storing a reference
 
52
in the 'layer' attribute.
 
53
 
 
54
>>> import unittest
 
55
>>> class TestSpecifyingBaseLayer(unittest.TestCase):
 
56
...     'This TestCase explicitly specifies its layer'
 
57
...     layer = BaseLayer
 
58
...     name = 'TestSpecifyingBaseLayer' # For testing only
 
59
...
 
60
...     def setUp(self):
 
61
...         log('TestSpecifyingBaseLayer.setUp')
 
62
...
 
63
...     def tearDown(self):
 
64
...         log('TestSpecifyingBaseLayer.tearDown')
 
65
...
 
66
...     def test1(self):
 
67
...         log('TestSpecifyingBaseLayer.test1')
 
68
...
 
69
...     def test2(self):
 
70
...         log('TestSpecifyingBaseLayer.test2')
 
71
...
 
72
>>> class TestSpecifyingNoLayer(unittest.TestCase):
 
73
...     'This TestCase specifies no layer'
 
74
...     name = 'TestSpecifyingNoLayer' # For testing only
 
75
...     def setUp(self):
 
76
...         log('TestSpecifyingNoLayer.setUp')
 
77
...
 
78
...     def tearDown(self):
 
79
...         log('TestSpecifyingNoLayer.tearDown')
 
80
...
 
81
...     def test1(self):
 
82
...         log('TestSpecifyingNoLayer.test')
 
83
...
 
84
...     def test2(self):
 
85
...         log('TestSpecifyingNoLayer.test')
 
86
...
 
87
 
 
88
Create a TestSuite containing two test suites, one for each of
 
89
TestSpecifyingBaseLayer and TestSpecifyingNoLayer.
 
90
 
 
91
>>> umbrella_suite = unittest.TestSuite()
 
92
>>> umbrella_suite.addTest(unittest.makeSuite(TestSpecifyingBaseLayer))
 
93
>>> no_layer_suite = unittest.makeSuite(TestSpecifyingNoLayer)
 
94
>>> umbrella_suite.addTest(no_layer_suite)
 
95
 
 
96
Before we can run the tests, we need to setup some helpers.
 
97
 
 
98
>>> from zope.testing.testrunner import options
 
99
>>> from zope.testing.loggingsupport import InstalledHandler
 
100
>>> import logging
 
101
>>> log_handler = InstalledHandler('zope.testing.tests')
 
102
>>> def log(msg):
 
103
...     logging.getLogger('zope.testing.tests').info(msg)
 
104
>>> def fresh_options():
 
105
...     opts = options.get_options(['--test-filter', '.*'])
 
106
...     opts.resume_layer = None
 
107
...     opts.resume_number = 0
 
108
...     return opts
 
109
 
 
110
Now we run the tests. Note that the BaseLayer was not setup when
 
111
the TestSpecifyingNoLayer was run and setup/torn down around the
 
112
TestSpecifyingBaseLayer tests.
 
113
 
 
114
>>> from zope.testing.testrunner.runner import Runner
 
115
>>> runner = Runner(options=fresh_options(), args=[], found_suites=[umbrella_suite])
 
116
>>> succeeded = runner.run()
 
117
Running BaseLayer tests:
 
118
  Set up BaseLayer in N.NNN seconds.
 
119
  Ran 2 tests with 0 failures and 0 errors in N.NNN seconds.
 
120
Running zope.testing.testrunner.layer.UnitTests tests:
 
121
  Tear down BaseLayer in N.NNN seconds.
 
122
  Set up zope.testing.testrunner.layer.UnitTests in N.NNN seconds.
 
123
  Ran 2 tests with 0 failures and 0 errors in N.NNN seconds.
 
124
Tearing down left over layers:
 
125
  Tear down zope.testing.testrunner.layer.UnitTests in N.NNN seconds.
 
126
Total: 4 tests, 0 failures, 0 errors in N.NNN seconds.
 
127
 
 
128
 
 
129
Now lets specify a layer in the suite containing TestSpecifyingNoLayer
 
130
and run the tests again. This demonstrates the other method of specifying
 
131
a layer. This is generally how you specify what layer doctests need.
 
132
 
 
133
>>> no_layer_suite.layer = BaseLayer
 
134
>>> runner = Runner(options=fresh_options(), args=[], found_suites=[umbrella_suite])
 
135
>>> succeeded = runner.run()
 
136
Running BaseLayer tests:
 
137
  Set up BaseLayer in N.NNN seconds.
 
138
  Ran 4 tests with 0 failures and 0 errors in N.NNN seconds.
 
139
Tearing down left over layers:
 
140
  Tear down BaseLayer in N.NNN seconds.
 
141
 
 
142
Clear our logged output, as we want to inspect it shortly.
 
143
 
 
144
>>> log_handler.clear()
 
145
 
 
146
Now lets also specify a layer in the TestSpecifyingNoLayer class and rerun
 
147
the tests. This demonstrates that the most specific layer is used. It also
 
148
shows the behavior of nested layers - because TopLayer extends BaseLayer,
 
149
both the BaseLayer and TopLayer environments are setup when the
 
150
TestSpecifyingNoLayer tests are run.
 
151
 
 
152
>>> TestSpecifyingNoLayer.layer = TopLayer
 
153
>>> runner = Runner(options=fresh_options(), args=[], found_suites=[umbrella_suite])
 
154
>>> succeeded = runner.run()
 
155
Running BaseLayer tests:
 
156
  Set up BaseLayer in N.NNN seconds.
 
157
  Ran 2 tests with 0 failures and 0 errors in N.NNN seconds.
 
158
Running TopLayer tests:
 
159
  Set up TopLayer in N.NNN seconds.
 
160
  Ran 2 tests with 0 failures and 0 errors in N.NNN seconds.
 
161
Tearing down left over layers:
 
162
  Tear down TopLayer in N.NNN seconds.
 
163
  Tear down BaseLayer in N.NNN seconds.
 
164
Total: 4 tests, 0 failures, 0 errors in N.NNN seconds.
 
165
 
 
166
 
 
167
If we inspect our trace of what methods got called in what order, we can
 
168
see that the layer setup and teardown methods only got called once. We can
 
169
also see that the layer's test setup and teardown methods got called for
 
170
each test using that layer in the right order.
 
171
 
 
172
>>> def report():
 
173
...     for record in log_handler.records:
 
174
...         print record.getMessage()
 
175
>>> report()
 
176
BaseLayer.setUp
 
177
BaseLayer.testSetUp
 
178
TestSpecifyingBaseLayer.setUp
 
179
TestSpecifyingBaseLayer.test1
 
180
TestSpecifyingBaseLayer.tearDown
 
181
BaseLayer.testTearDown
 
182
BaseLayer.testSetUp
 
183
TestSpecifyingBaseLayer.setUp
 
184
TestSpecifyingBaseLayer.test2
 
185
TestSpecifyingBaseLayer.tearDown
 
186
BaseLayer.testTearDown
 
187
TopLayer.setUp
 
188
BaseLayer.testSetUp
 
189
TopLayer.testSetUp
 
190
TestSpecifyingNoLayer.setUp
 
191
TestSpecifyingNoLayer.test
 
192
TestSpecifyingNoLayer.tearDown
 
193
TopLayer.testTearDown
 
194
BaseLayer.testTearDown
 
195
BaseLayer.testSetUp
 
196
TopLayer.testSetUp
 
197
TestSpecifyingNoLayer.setUp
 
198
TestSpecifyingNoLayer.test
 
199
TestSpecifyingNoLayer.tearDown
 
200
TopLayer.testTearDown
 
201
BaseLayer.testTearDown
 
202
TopLayer.tearDown
 
203
BaseLayer.tearDown
 
204
 
 
205
Now lets stack a few more layers to ensure that our setUp and tearDown
 
206
methods are called in the correct order.
 
207
 
 
208
>>> from zope.testing.testrunner.find import name_from_layer
 
209
>>> class A(object):
 
210
...     def setUp(cls):
 
211
...         log('%s.setUp' % name_from_layer(cls))
 
212
...     setUp = classmethod(setUp)
 
213
...
 
214
...     def tearDown(cls):
 
215
...         log('%s.tearDown' % name_from_layer(cls))
 
216
...     tearDown = classmethod(tearDown)
 
217
...
 
218
...     def testSetUp(cls):
 
219
...         log('%s.testSetUp' % name_from_layer(cls))
 
220
...     testSetUp = classmethod(testSetUp)
 
221
...
 
222
...     def testTearDown(cls):
 
223
...         log('%s.testTearDown' % name_from_layer(cls))
 
224
...     testTearDown = classmethod(testTearDown)
 
225
...         
 
226
>>> class B(A): pass
 
227
>>> class C(B): pass
 
228
>>> class D(A): pass
 
229
>>> class E(D): pass
 
230
>>> class F(C,E): pass
 
231
 
 
232
>>> class DeepTest(unittest.TestCase):
 
233
...     layer = F
 
234
...     def test(self):
 
235
...         pass
 
236
>>> suite = unittest.makeSuite(DeepTest)
 
237
>>> log_handler.clear()
 
238
>>> runner = Runner(options=fresh_options(), args=[], found_suites=[suite])
 
239
>>> succeeded = runner.run()
 
240
Running F tests:
 
241
  Set up A in N.NNN seconds.
 
242
  Set up B in N.NNN seconds.
 
243
  Set up C in N.NNN seconds.
 
244
  Set up D in N.NNN seconds.
 
245
  Set up E in N.NNN seconds.
 
246
  Set up F in N.NNN seconds.
 
247
  Ran 1 tests with 0 failures and 0 errors in N.NNN seconds.
 
248
Tearing down left over layers:
 
249
  Tear down F in N.NNN seconds.
 
250
  Tear down E in N.NNN seconds.
 
251
  Tear down D in N.NNN seconds.
 
252
  Tear down C in N.NNN seconds.
 
253
  Tear down B in N.NNN seconds.
 
254
  Tear down A in N.NNN seconds.
 
255
 
 
256
 
 
257
>>> report()
 
258
A.setUp
 
259
B.setUp
 
260
C.setUp
 
261
D.setUp
 
262
E.setUp
 
263
F.setUp
 
264
A.testSetUp
 
265
B.testSetUp
 
266
C.testSetUp
 
267
D.testSetUp
 
268
E.testSetUp
 
269
F.testSetUp
 
270
F.testTearDown
 
271
E.testTearDown
 
272
D.testTearDown
 
273
C.testTearDown
 
274
B.testTearDown
 
275
A.testTearDown
 
276
F.tearDown
 
277
E.tearDown
 
278
D.tearDown
 
279
C.tearDown
 
280
B.tearDown
 
281
A.tearDown