单元测试(使用unittest
模块)使用App Engine testbed,我需要setUp
和tearDown
方法来激活和分别停用测试台,(略微简化的):使用类装饰器,如何重写方法而不重新定义类?
class SomeTest(unittest.TestCase):
def setUp(self):
self.testbed = testbed.Testbed()
self.testbed.activate()
def tearDown(self):
self.testbed.deactivate()
def testSomething(self):
...
这很快变得写的负担。我可以编写一个基类TestCaseWithTestbed
,但是我必须记得每次在其中一个测试用例中需要自定义的setUp
时调用超类方法。
我认为用类装饰器来解决这个问题会更优雅。所以我想写:
@WithTestbed
class SomeTest(unittest.TestCase):
def testSomething(self):
...
随着这个装饰应用,试验台应该只是神奇地激活。那么......如何实现装饰者WithTestbed
?目前,我有以下几点:
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
这适用于简单的情况,但有一些严重的问题:
- 测试类的名称将成为
ClsWithTestbed
,这表明了测试输出。 - 调用
super(SomeTestClass, self).setUp()
的具体测试类以无限递归结束,因为SomeTestClass
现在等于WithTestbed
。
我对Python的运行时类型操作有些朦胧。那么,如何以正确的方式做到这一点?
你不只是继承'setUp'?普通子类有什么问题?为什么惹恼装饰者? – 2012-01-12 15:45:05
如果我在特定的测试用例中有其他设置任务,我必须记得调用'super(SomeTestCase,self).setUp()'。这很丑陋。 – Thomas 2012-01-12 15:48:48
它可能很难看,但它是标准的,普通的,正常的Pythonic方法。 – 2012-01-12 15:49:32