summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Collins <robertc@robertcollins.net>2010-01-11 22:18:13 +1100
committerRobert Collins <robertc@robertcollins.net>2010-01-11 22:18:13 +1100
commitd188292a7cce5d6768add4aeb1195da752ba57b9 (patch)
treecdcefbb45d61141e96e442c335f3f24c9836a2c0
parent25d8fb101adb930432ad232a15bce2baafdb6dfa (diff)
parent492f351bb868ea0ec9f5dde58b0e420870e698a5 (diff)
downloadtestresources-d188292a7cce5d6768add4aeb1195da752ba57b9.tar.gz
Implement an adapter for existing fixtures that honour a setUp/tearDown like protocol.
-rw-r--r--NEWS3
-rw-r--r--lib/testresources/__init__.py44
-rw-r--r--lib/testresources/tests/test_test_resource.py60
3 files changed, 107 insertions, 0 deletions
diff --git a/NEWS b/NEWS
index 37d91f9..2a5e4be 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,9 @@ CHANGES
IMPROVEMENTS
~~~~~~~~~~~~
+* New helper testresources.GenericResource which should remove the need for
+ much boilerplate when using testresources with existing test fixtures.
+
BUG FIXES
~~~~~~~~~
diff --git a/lib/testresources/__init__.py b/lib/testresources/__init__.py
index b9854a5..859584b 100644
--- a/lib/testresources/__init__.py
+++ b/lib/testresources/__init__.py
@@ -17,6 +17,8 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
+"""TestResources: declarative management of external resources for tests."""
+
import inspect
import unittest
@@ -354,6 +356,48 @@ class TestResource(object):
self._dirty = False
+class GenericResource(TestResource):
+ """A TestResource that decorates an external helper of some kind.
+
+ GenericResource can be used to adapt an external resource so that
+ testresources can use it. By default the setUp and tearDown methods are
+ called when making and cleaning the resource, and the resource is
+ considered permanently dirty, so it is torn down and brought up again
+ between every use.
+
+ The constructor method is called with the dependency resources dict::
+ resource_factory(**dependency_resources)
+ This permits naming those resources to match the contract of the setUp
+ method.
+ """
+
+ def __init__(self, resource_factory, setup_method_name='setUp',
+ teardown_method_name='tearDown'):
+ """Create a GenericResource
+
+ :param resource_factory: A factory to create a new resource.
+ :param setup_method_name: Optional method name to call to setup the
+ resource. Defaults to 'setUp'.
+ :param teardown_method_name: Optional method name to call to tear down
+ the resource. Defaults to 'tearDown'.
+ """
+ TestResource.__init__(self)
+ self.resource_factory = resource_factory
+ self.setup_method_name = setup_method_name
+ self.teardown_method_name = teardown_method_name
+
+ def clean(self, resource):
+ getattr(resource, self.teardown_method_name)()
+
+ def make(self, dependency_resources):
+ result = self.resource_factory(**dependency_resources)
+ getattr(result, self.setup_method_name)()
+ return result
+
+ def isDirty(self):
+ return True
+
+
class ResourcedTestCase(unittest.TestCase):
"""A TestCase parent or utility that enables cross-test resource usage.
diff --git a/lib/testresources/tests/test_test_resource.py b/lib/testresources/tests/test_test_resource.py
index e0d1ec4..70e8921 100644
--- a/lib/testresources/tests/test_test_resource.py
+++ b/lib/testresources/tests/test_test_resource.py
@@ -389,3 +389,63 @@ class TestTestResource(testtools.TestCase):
resource_manager.finishedWith(r)
resource_manager.finishedWith(resource_manager._currentResource)
self.assertEqual(expected, result._calls)
+
+
+class TestGenericResource(testtools.TestCase):
+
+ def test_default_uses_setUp_tearDown(self):
+ calls = []
+ class Wrapped:
+ def setUp(self):
+ calls.append('setUp')
+ def tearDown(self):
+ calls.append('tearDown')
+ mgr = testresources.GenericResource(Wrapped)
+ resource = mgr.getResource()
+ self.assertEqual(['setUp'], calls)
+ mgr.finishedWith(resource)
+ self.assertEqual(['setUp', 'tearDown'], calls)
+ self.assertIsInstance(resource, Wrapped)
+
+ def test_dependencies_passed_to_factory(self):
+ calls = []
+ class Wrapped:
+ def __init__(self, **args):
+ calls.append(args)
+ def setUp(self):pass
+ def tearDown(self):pass
+ class Trivial(testresources.TestResource):
+ def __init__(self, thing):
+ testresources.TestResource.__init__(self)
+ self.thing = thing
+ def make(self, dependency_resources):return self.thing
+ def clean(self, resource):pass
+ mgr = testresources.GenericResource(Wrapped)
+ mgr.resources = [('foo', Trivial('foo')), ('bar', Trivial('bar'))]
+ resource = mgr.getResource()
+ self.assertEqual([{'foo':'foo', 'bar':'bar'}], calls)
+ mgr.finishedWith(resource)
+
+ def test_setup_teardown_controllable(self):
+ calls = []
+ class Wrapped:
+ def start(self):
+ calls.append('setUp')
+ def stop(self):
+ calls.append('tearDown')
+ mgr = testresources.GenericResource(Wrapped,
+ setup_method_name='start', teardown_method_name='stop')
+ resource = mgr.getResource()
+ self.assertEqual(['setUp'], calls)
+ mgr.finishedWith(resource)
+ self.assertEqual(['setUp', 'tearDown'], calls)
+ self.assertIsInstance(resource, Wrapped)
+
+ def test_always_dirty(self):
+ class Wrapped:
+ def setUp(self):pass
+ def tearDown(self):pass
+ mgr = testresources.GenericResource(Wrapped)
+ resource = mgr.getResource()
+ self.assertTrue(mgr.isDirty())
+ mgr.finishedWith(resource)