[TIP] unittest 0.2.0: class and module level fixtures
Michael Foord
fuzzyman at voidspace.org.uk
Fri Mar 5 16:55:20 PST 2010
Hello all,
unittest2 0.2.0 is out. unittest2 now has class and module level
fixtures: setUpClass, setUpModule, tearDownClass, tearDownModule.
http://pypi.python.org/pypi/unittest2/
Install with: "pip install -U unittest2"
These features are tested but I'm sure there are some lurking bugs or
oddities, so please try it out.
* Implementation: http://hg.python.org/unittest2/file/tip/unittest2/suite.py
* Tests:
http://hg.python.org/unittest2/file/tip/unittest2/test/test_shared_fixtures.py
Below are some notes on how they work.
Class and module level fixtures are implemented in unittest2.TestSuite.
When the test suite encounters a test from a new class then
tearDownClass from the previous class (if there is one) is called,
followed by setUpClass from the new class.
Similarly if a test is from a different module from the previous test
then tearDownModule from the previous module is run, followed by
setUpModule from the new module.
After all the tests in the suite have run the final tearDownClass and
tearDownModule are run.
The default ordering of tests created by the unittest test loaders is to
group all tests from the same modules and classes together. This will
lead to setUpClass / setUpModule (etc) being called exactly once per
class and module. If you randomize the order so that tests from
different modules and classes are adjacent to each other then these
shared fixture functions may be called multiple times.
If there are any exceptions raised during one of these functions /
methods then the test is reported as an error. Because there is no
corresponding test instance an _ErrorHolder object (that has the same
interface as a TestCase) is created to represent the error. If you are
just using the standard unittest2 test runner then this detail doesn't
matter, but if you are a framework author it may be relevant.
If there is demand for it, it would be possible to add a 'randomize'
option to the test loaders that will randomize the order of test modules
in a suite, the order of test classes within modules and the order of
tests within a class. This will allow for tests to be run in a somewhat
random order whilst maintaining an order properly compatible with shared
fixtures.
Note that shared fixtures do not play well with features like test
parallelization and they also break test isolation. They should be used
with care.
setUpClass and tearDownClass
--------------------------------------
These must be implemented as class methods.
import unittest2
class Test(unittest2.TestCase):
@classmethod
def setUpClass(cls):
cls._connection = createExpensiveConnectionObject()
@classmethod
def tearDownClass(cls):
cls._connection.destroy()
If you want the setUpClass and tearDownClass on base classes called then
you must call up to them yourself. The implementations in
unittest2.TestCase are empty.
If an exception is raised during a setUpClass then the tests in the
class are not run and the tearDownClass is not run. Skipped classes will
not have setUpClass or tearDownClass run.
A setUpClass that raises a unittest2.SkipTest exception will currently
be reported as an error rather than a skip (although the effect is the
same). This will be fixed at some point in the future.
setUpModule and tearDownModule
--------------------------------------------
These should be implemented as functions.
def setUpModule():
createConnection()
def tearDownModule():
closeConnection()
If an exception is raised in a setUpModule then none of the tests in the
module will be run and the tearDownModule will not be run.
A setUpModule that raises a unittest2.SkipTest exception will currently
be reported as an error rather than a skip (although the effect is the
same). This will be fixed at some point in the future.
--
http://www.ironpythoninaction.com/
http://www.voidspace.org.uk/blog
READ CAREFULLY. By accepting and reading this email you agree, on behalf
of your employer, to release me from all obligations and waivers arising
from any and all NON-NEGOTIATED agreements, licenses, terms-of-service,
shrinkwrap, clickwrap, browsewrap, confidentiality, non-disclosure,
non-compete and acceptable use policies (”BOGUS AGREEMENTS”) that I have
entered into with your employer, its partners, licensors, agents and
assigns, in perpetuity, without prejudice to my ongoing rights and
privileges. You further represent that you have the authority to release
me from any BOGUS AGREEMENTS on behalf of your employer.
More information about the testing-in-python
mailing list