~ubuntu-branches/ubuntu/saucy/testresources/saucy-proposed

« back to all changes in this revision

Viewing changes to README

  • Committer: Bazaar Package Importer
  • Author(s): Robert Collins
  • Date: 2010-02-27 10:04:22 UTC
  • mfrom: (1.1.5 upstream) (2.1.6 sid)
  • Revision ID: james.westby@ubuntu.com-20100227100422-lt9yiszrs23wl8r3
Tags: 0.2.4-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
testresources: extensions to python unittest to allow declaritive use
 
1
testresources: extensions to python unittest to allow declarative use
2
2
of resources by test cases.
3
3
 
4
 
Copyright (C) 2005-2008  Robert Collins <robertc@robertcollins.net>
5
 
 
6
 
  This program is free software; you can redistribute it and/or modify
7
 
  it under the terms of the GNU General Public License as published by
8
 
  the Free Software Foundation; either version 2 of the License, or
9
 
  (at your option) any later version.
10
 
 
11
 
  This program is distributed in the hope that it will be useful,
12
 
  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
  GNU General Public License for more details.
15
 
 
16
 
  You should have received a copy of the GNU General Public License
17
 
  along with this program; if not, write to the Free Software
18
 
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 
 
 
4
Copyright (C) 2005-2010  Robert Collins <robertc@robertcollins.net>
 
5
 
 
6
  Licensed under either the Apache License, Version 2.0 or the BSD 3-clause
 
7
  license at the users choice. A copy of both licenses are available in the
 
8
  project source as Apache-2.0 and BSD. You may not use this file except in
 
9
  compliance with one of these two licences.
 
10
  
 
11
  Unless required by applicable law or agreed to in writing, software
 
12
  distributed under these licenses is distributed on an "AS IS" BASIS, WITHOUT
 
13
  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
 
14
  license you chose for the specific language governing permissions and
 
15
  limitations under that license.
 
16
 
 
17
  See the COPYING file for full details on the licensing of Testresources.
 
18
 
 
19
 
 
20
Testresources
 
21
+++++++++++++
20
22
 
21
23
testresources is attempting to extend unittest with a clean and simple api to
22
24
provide test optimisation where expensive common resources are needed for test
23
25
cases - for example sample working trees for VCS systems, reference databases
24
26
for enterprise applications, or web servers ... let imagination run wild.
25
27
 
26
 
Dependencies:
27
 
=============
 
28
Dependencies
 
29
============
28
30
 
29
31
* Python 2.4+
30
32
* testtools
33
35
can use testresources in your own app without using testtools.
34
36
 
35
37
 
36
 
How testresources works:
37
 
========================
38
 
 
39
 
These are the main components to make testresources work:
40
 
 
41
 
1) testresources.TestResource
42
 
 
43
 
A TestResource is an object that tests can use. Usually a subclass of
44
 
testresources.TestResource, with the make and possibly the clean and isDirty
45
 
methods overridden. These methods create, decide on reuse and free resources.
46
 
 
47
 
The 'resources' list on the TestResource object is used to declare
 
38
How testresources Works
 
39
=======================
 
40
 
 
41
The basic idea of testresources is:
 
42
 
 
43
* Tests declare the resources they need in a ``resources`` attribute.
 
44
* When the test is run, the required resource objects are allocated (either 
 
45
  newly constructed, or reused), and assigned to attributes of the TestCase.
 
46
 
 
47
testresources distinguishes a 'resource manager' (a subclass of 
 
48
``TestResourceManager``) which acts as a kind of factory, and a 'resource'
 
49
which can be any kind of object returned from the manager class's
 
50
``getResource`` method.
 
51
 
 
52
Resources are either clean or dirty.  Being clean means they have same state in
 
53
all important ways as a newly constructed instance and they can therefore be
 
54
safely reused.
 
55
 
 
56
Main Classes
 
57
============
 
58
 
 
59
testresources.ResourcedTestCase
 
60
-------------------------------
 
61
 
 
62
By extending or mixing-in this class, tests can have necessary resources
 
63
automatically allocated and disposed or recycled.
 
64
 
 
65
ResourceTestCase can be used as a base class for tests, and when that is done
 
66
tests will have their ``resources`` attribute automatically checked for
 
67
resources by both OptimisingTestSuite and their own setUp() and tearDown()
 
68
methods. (This allows tests to remain functional without needing this specific
 
69
TestSuite as a container). Alternatively, you can call setUpResources(self,
 
70
resources, test_result) and tearDownResources(self, resources, test_result)
 
71
from your own classes setUp and tearDown and the same behaviour will be
 
72
activated.
 
73
 
 
74
To declare the use of a resource, set the ``resources`` attribute to a list of
 
75
tuples of ``(attribute_name, resource_factory)``.
 
76
 
 
77
During setUp, for each declared requirement, the test gains an attribute
 
78
pointing to an allocated resource, which is the result of calling
 
79
``resource_factory.getResource()``.  ``finishedWith`` will be called on each
 
80
resource during tearDown().
 
81
 
 
82
For example::
 
83
 
 
84
    class TestLog(testresources.TestCase):
 
85
 
 
86
        resources = [('branch', BzrPopulatedBranch())]
 
87
 
 
88
        def test_log(self):
 
89
            show_log(self.branch, ...)
 
90
 
 
91
testresources.TestResourceManager
 
92
---------------------------------
 
93
 
 
94
A TestResourceManager is an object that tests can use to create resources.  It
 
95
can be overridden to manage different types of resources.  Normally test code
 
96
doesn't need to call any methods on it, as this will be arranged by the
 
97
testresources machinery.
 
98
 
 
99
When implementing a new ``TestResourceManager`` subclass you should consider
 
100
overriding these methods:
 
101
 
 
102
``make``
 
103
    Must be overridden in every concrete subclass.  
 
104
 
 
105
    Returns a new instance of the resource object
 
106
    (the actual resource, not the TestResourceManager).  Doesn't need to worry about 
 
107
    reuse, which is taken care of separately.  This method is only called when a 
 
108
    new resource is definitely needed.  
 
109
 
 
110
``clean``
 
111
    Cleans up an existing resource instance, eg by deleting a directory or 
 
112
    closing a network connection.  By default this does nothing, which may be 
 
113
    appropriate for resources that are automatically garbage collected.
 
114
 
 
115
``reset``
 
116
    Reset a no-longer-used dirty resource to a clean state.  By default this
 
117
    just discards it and creates a new one, but for some resources there may be a
 
118
    faster way to reset them.
 
119
 
 
120
``isDirty``
 
121
    Check whether an existing resource is dirty.  By default this just reports whether 
 
122
    ``TestResourceManager.dirtied`` has been called.
 
123
 
 
124
For instance::
 
125
 
 
126
    class TemporaryDirectoryResource(TestResourceManager):
 
127
 
 
128
        def clean(self, resource):
 
129
            osutils.rmtree(resource) 
 
130
 
 
131
        def make(self):
 
132
            return tempfile.mkdtemp()
 
133
 
 
134
        def isDirty(self, resource):
 
135
            # Can't detect when the directory is written to, so assume it 
 
136
            # can never be reused.  We could list the directory, but that might
 
137
            # not catch it being open as a cwd etc.
 
138
            return True
 
139
 
 
140
The ``resources`` list on the TestResourceManager object is used to declare
48
141
dependencies. For instance, a DataBaseResource that needs a TemporaryDirectory
49
142
might be declared with a resources list::
50
143
 
51
 
    class DataBaseResource(TestResource):
 
144
    class DataBaseResource(TestResourceManager):
52
145
 
53
146
        resources = [("scratchdir", TemporaryDirectoryResource())]
54
147
 
55
 
Most importantly, two getResources to the same TestResource with no
56
 
finishedWith call in the middle, will return the same object as long as it has
57
 
not been marked dirty.
 
148
Most importantly, two getResources to the same TestResourceManager with no
 
149
finishedWith call in the middle, will return the same object as long as it is
 
150
not dirty.
58
151
 
59
152
When a Test has a dependency and that dependency successfully completes but
60
153
returns None, the framework does *not* consider this an error: be sure to always
61
154
return a valid resource, or raise an error. Error handling hasn't been heavily
62
155
exercised, but any bugs in this area will be promptly dealt with.
63
156
 
64
 
A sample TestResource can be found in the doc/ folder.
65
 
 
66
 
See pydoc testresources.TestResource for details.
67
 
 
68
 
 
69
 
2) testresources.OptimisingTestSuite
 
157
A sample TestResourceManager can be found in the doc/ folder.
 
158
 
 
159
See pydoc testresources.TestResourceManager for details.
 
160
 
 
161
testresources.GenericResource
 
162
-----------------------------
 
163
 
 
164
Glue to adapt testresources to an existing resource-like class.
 
165
 
 
166
testresources.OptimisingTestSuite
 
167
---------------------------------
70
168
 
71
169
This TestSuite will introspect all the test cases it holds directly and if
72
170
they declare needed resources, will run the tests in an order that attempts to
87
185
OptimisingTestSuites.
88
186
 
89
187
 
90
 
3) testresources.ResourcedTestCase
91
 
 
92
 
ResourceTestCase can be used as a base class for tests, and when that is done
93
 
tests will have their resources attribute automatically checked for resources
94
 
by both OptimisingTestSuite and their own setUp() and tearDown() methods.
95
 
(This allows tests to remain functional without needing this specific
96
 
TestSuite as a container). Alternatively, you can call
97
 
ResourceTestCase.setUpResources(self) and
98
 
ResourceTestCase.tearDownResources(self) from your own classes setUp and
99
 
tearDown and the same behaviour will be activated.
100
 
 
101
 
To declare the use of a resource, set resources as an attribute listing tuples
102
 
of (attribute name, TestResource). During setUp, self._attribute_name will be
103
 
set to TestResource.getResource(), and finishedWith() will be called for you
104
 
during tearDown().
105
 
 
106
 
 
107
 
4) testresources.TestLoader
 
188
testresources.TestLoader
 
189
------------------------
108
190
 
109
191
This is a trivial TestLoader that creates OptimisingTestSuites by default.
110
192
 
111
 
5) unittest.TestResult
 
193
unittest.TestResult
 
194
-------------------
112
195
 
113
196
testresources will log activity about resource creation and destruction to the
114
197
result object tests are run with. 4 extension methods are looked for:
115
198
``startCleanResource``, ``stopCleanResource``, ``startMakeResource``,
116
199
``stopMakeResource``. ``testresources.tests.ResultWithResourceExtensions`` is
117
200
an example of a ``TestResult`` with these methods present.
 
201
 
 
202
Controlling Resource Reuse
 
203
==========================
 
204
 
 
205
When or how do I mark the resource dirtied?
 
206
 
 
207
The simplest approach is to have ``TestResourceManager.make`` call ``self.dirtied``:
 
208
the resource is always immediately dirty and will never be reused without first
 
209
being reset.  This is appropriate when the underlying resource is cheap to
 
210
reset or recreate, or when it's hard to detect whether it's been dirtied or to
 
211
trap operations that change it.
 
212
 
 
213
Alternatively, override ``TestResourceManager.isDirty`` and inspect the resource to
 
214
see if it is safe to reuse.
 
215
 
 
216
Finally, you can arrange for the returned resource to always call back to
 
217
``TestResourceManager.dirtied`` on the first operation that mutates it.
 
218
 
 
219
FAQ
 
220
===
 
221
 
 
222
* Can I dynamically request resources inside a test method?
 
223
 
 
224
  Generally, no, you shouldn't do this.  The idea is that the resources are
 
225
  declared statically, so that testresources can "smooth" resource usage across
 
226
  several tests.
 
227
 
 
228
* If the resource is held inside the TestResourceManager object, and the
 
229
  TestResourceManager is typically constructed inline in the test case
 
230
  ``resources`` attribute, how can they be shared across different test
 
231
  classes?
 
232
 
 
233
  Good question.
 
234
 
 
235
  I guess you should arrange for a single instance to be held in an appropriate
 
236
  module scope, then referenced by the test classes that want to share it.