For unit tests (using the unittest
module) that use the App Engine testbed, I need setUp
and tearDown
methods to activate and deactivate the testbed, respectively (slightly simplified):
class SomeTest(unittest.TestCase):
def setUp(self):
self.testbed = testbed.Testbed()
self.testbed.activate()
def tearDown(self):
self.testbed.deactivate()
def testSomething(self):
...
This quickly becomes a burden to write. I could write a base class TestCaseWithTestbed
, but then I'd have to remember to call the superclass method each time I need a custom setUp
in one of the test cases.
I thought it would be more elegant to solve this with a class decorator instead. So I'd like to write:
@WithTestbed
class SomeTest(unittest.TestCase):
def testSomething(self):
...
With this decorator applied, the testbed should just be activated magically. So... how to implement the WithTestbed
decorator? I currently have the following:
def WithTestbed(cls):
class ClsWithTestbed(cls):
def setUp(self):
self.testbed = testbed.Testbed()
self.testbed.activate()
cls.setUp(self)
def tearDown(self):
cls.tearDown(self)
self.testbed.deactivate()
return ClsWithTestbed
This works for simple cases, but has some serious problems:
- The name of the test class becomes
ClsWithTestbed
and this shows up in the test output. - Concrete test classes calling
super(SomeTestClass, self).setUp()
end up in an infinite recursion, becauseSomeTestClass
is now equal toWithTestbed
.
I'm a bit hazy on Python's runtime type manipulation. So, how to do this the Right Way?