s4:dsdb/operational: fix stripping of the nTSecurityDescriptor attribute
[Samba/gebeck_regimport.git] / lib / testtools / doc / for-framework-folk.rst
blobff9e71e71ea235b5f76bf01ac765aaac0902287d
1 ============================
2 testtools for framework folk
3 ============================
5 Introduction
6 ============
8 In addition to having many features :doc:`for test authors
9 <for-test-authors>`, testtools also has many bits and pieces that are useful
10 for folk who write testing frameworks.
12 If you are the author of a test runner, are working on a very large
13 unit-tested project, are trying to get one testing framework to play nicely
14 with another or are hacking away at getting your test suite to run in parallel
15 over a heterogenous cluster of machines, this guide is for you.
17 This manual is a summary.  You can get details by consulting the `testtools
18 API docs`_.
21 Extensions to TestCase
22 ======================
24 Custom exception handling
25 -------------------------
27 testtools provides a way to control how test exceptions are handled.  To do
28 this, add a new exception to ``self.exception_handlers`` on a
29 ``testtools.TestCase``.  For example::
31     >>> self.exception_handlers.insert(-1, (ExceptionClass, handler)).
33 Having done this, if any of ``setUp``, ``tearDown``, or the test method raise
34 ``ExceptionClass``, ``handler`` will be called with the test case, test result
35 and the raised exception.
37 Use this if you want to add a new kind of test result, that is, if you think
38 that ``addError``, ``addFailure`` and so forth are not enough for your needs.
41 Controlling test execution
42 --------------------------
44 If you want to control more than just how exceptions are raised, you can
45 provide a custom ``RunTest`` to a ``TestCase``.  The ``RunTest`` object can
46 change everything about how the test executes.
48 To work with ``testtools.TestCase``, a ``RunTest`` must have a factory that
49 takes a test and an optional list of exception handlers.  Instances returned
50 by the factory must have a ``run()`` method that takes an optional ``TestResult``
51 object.
53 The default is ``testtools.runtest.RunTest``, which calls ``setUp``, the test
54 method, ``tearDown`` and clean ups (see :ref:`addCleanup`) in the normal, vanilla
55 way that Python's standard unittest_ does.
57 To specify a ``RunTest`` for all the tests in a ``TestCase`` class, do something
58 like this::
60   class SomeTests(TestCase):
61       run_tests_with = CustomRunTestFactory
63 To specify a ``RunTest`` for a specific test in a ``TestCase`` class, do::
65   class SomeTests(TestCase):
66       @run_test_with(CustomRunTestFactory, extra_arg=42, foo='whatever')
67       def test_something(self):
68           pass
70 In addition, either of these can be overridden by passing a factory in to the
71 ``TestCase`` constructor with the optional ``runTest`` argument.
74 Test renaming
75 -------------
77 ``testtools.clone_test_with_new_id`` is a function to copy a test case
78 instance to one with a new name.  This is helpful for implementing test
79 parameterization.
82 Test placeholders
83 =================
85 Sometimes, it's useful to be able to add things to a test suite that are not
86 actually tests.  For example, you might wish to represents import failures
87 that occur during test discovery as tests, so that your test result object
88 doesn't have to do special work to handle them nicely.
90 testtools provides two such objects, called "placeholders": ``PlaceHolder``
91 and ``ErrorHolder``.  ``PlaceHolder`` takes a test id and an optional
92 description.  When it's run, it succeeds.  ``ErrorHolder`` takes a test id,
93 and error and an optional short description.  When it's run, it reports that
94 error.
96 These placeholders are best used to log events that occur outside the test
97 suite proper, but are still very relevant to its results.
99 e.g.::
101   >>> suite = TestSuite()
102   >>> suite.add(PlaceHolder('I record an event'))
103   >>> suite.run(TextTestResult(verbose=True))
104   I record an event                                                   [OK]
107 Extensions to TestResult
108 ========================
110 TestResult.addSkip
111 ------------------
113 This method is called on result objects when a test skips. The
114 ``testtools.TestResult`` class records skips in its ``skip_reasons`` instance
115 dict. The can be reported on in much the same way as succesful tests.
118 TestResult.time
119 ---------------
121 This method controls the time used by a ``TestResult``, permitting accurate
122 timing of test results gathered on different machines or in different threads.
123 See pydoc testtools.TestResult.time for more details.
126 ThreadsafeForwardingResult
127 --------------------------
129 A ``TestResult`` which forwards activity to another test result, but synchronises
130 on a semaphore to ensure that all the activity for a single test arrives in a
131 batch. This allows simple TestResults which do not expect concurrent test
132 reporting to be fed the activity from multiple test threads, or processes.
134 Note that when you provide multiple errors for a single test, the target sees
135 each error as a distinct complete test.
138 MultiTestResult
139 ---------------
141 A test result that dispatches its events to many test results.  Use this
142 to combine multiple different test result objects into one test result object
143 that can be passed to ``TestCase.run()`` or similar.  For example::
145   a = TestResult()
146   b = TestResult()
147   combined = MultiTestResult(a, b)
148   combined.startTestRun()  # Calls a.startTestRun() and b.startTestRun()
150 Each of the methods on ``MultiTestResult`` will return a tuple of whatever the
151 component test results return.
154 TestResultDecorator
155 -------------------
157 Not strictly a ``TestResult``, but something that implements the extended
158 ``TestResult`` interface of testtools.  It can be subclassed to create objects
159 that wrap ``TestResults``.
162 TextTestResult
163 --------------
165 A ``TestResult`` that provides a text UI very similar to the Python standard
166 library UI. Key differences are that its supports the extended outcomes and
167 details API, and is completely encapsulated into the result object, permitting
168 it to be used without a 'TestRunner' object. Not all the Python 2.7 outcomes
169 are displayed (yet). It is also a 'quiet' result with no dots or verbose mode.
170 These limitations will be corrected soon.
173 ExtendedToOriginalDecorator
174 ---------------------------
176 Adapts legacy ``TestResult`` objects, such as those found in older Pythons, to
177 meet the testtools ``TestResult`` API.
180 Test Doubles
181 ------------
183 In testtools.testresult.doubles there are three test doubles that testtools
184 uses for its own testing: ``Python26TestResult``, ``Python27TestResult``,
185 ``ExtendedTestResult``. These TestResult objects implement a single variation of
186 the TestResult API each, and log activity to a list ``self._events``. These are
187 made available for the convenience of people writing their own extensions.
190 startTestRun and stopTestRun
191 ----------------------------
193 Python 2.7 added hooks ``startTestRun`` and ``stopTestRun`` which are called
194 before and after the entire test run. 'stopTestRun' is particularly useful for
195 test results that wish to produce summary output.
197 ``testtools.TestResult`` provides default ``startTestRun`` and ``stopTestRun``
198 methods, and he default testtools runner will call these methods
199 appropriately.
201 The ``startTestRun`` method will reset any errors, failures and so forth on
202 the result, making the result object look as if no tests have been run.
205 Extensions to TestSuite
206 =======================
208 ConcurrentTestSuite
209 -------------------
211 A TestSuite for parallel testing. This is used in conjuction with a helper that
212 runs a single suite in some parallel fashion (for instance, forking, handing
213 off to a subprocess, to a compute cloud, or simple threads).
214 ConcurrentTestSuite uses the helper to get a number of separate runnable
215 objects with a run(result), runs them all in threads using the
216 ThreadsafeForwardingResult to coalesce their activity.
218 FixtureSuite
219 ------------
221 A test suite that sets up a fixture_ before running any tests, and then tears
222 it down after all of the tests are run. The fixture is *not* made available to
223 any of the tests.
225 .. _`testtools API docs`: http://mumak.net/testtools/apidocs/
226 .. _unittest: http://docs.python.org/library/unittest.html
227 .. _fixture: http://pypi.python.org/pypi/fixtures