【问题标题】:How can I create a class-scoped test fixture in pyUnit?如何在 pyUnit 中创建类范围的测试夹具?
【发布时间】:2013-12-17 22:09:41
【问题描述】:
我正在对 mercurial 集成进行单元测试,并且有一个测试类,该测试类当前在其 setUp 方法中创建一个包含文件和该存储库克隆的存储库,并在其 tearDown 中删除它们em> 方法。
正如您可能想象的那样,这会非常快地获得相当大的性能,特别是如果我必须为每个测试单独执行此操作。
所以我想做的是创建文件夹并在加载类时初始化它们,以便 TestCase 类中的每个单元测试都可以使用这些存储库。然后,当所有测试都运行时,我想删除它们。我的 setUp 和 tearDown 方法唯一需要注意的是两个存储库在每次测试之间处于相同的状态。
基本上我正在寻找的是一个 python 等效于 JUnit 的 @BeforeClass 和 @AfterClass 注释。
【问题讨论】:
标签:
python
unit-testing
python-unittest
【解决方案1】:
我现在通过继承 TestSuite 类来完成它,因为标准加载器将所有测试方法包装在一个定义它们的 TestCase 实例中,并将它们放在一个 TestSuite 中。我让 TestSuite 调用第一个 TestCase 的 before() 和 after() 方法。这当然意味着您不能为您的 TestCase 对象初始化任何值,但您可能还是希望在您的设置中执行此操作。
TestSuite 如下所示:
class BeforeAfterSuite(unittest.TestSuite):
def run(self, result):
if len(self._tests) < 1:
return unittest.TestSuite.run(self, result)
first_test = self._tests[0]
if "before" in dir(first_test):
first_test.before()
result = unittest.TestSuite.run(self, result)
if "after" in dir(first_test):
first_test.after()
return result
对于一些更细粒度的控件,我还创建了自定义 TestLoader,它确保 BeforeAfterSuite 仅用于包装 test-method-TestCase 对象,如下所示:
class BeforeAfterLoader(unittest.TestLoader):
def loadTestsFromTestCase(self, testCaseClass):
self.suiteClass = BeforeAfterSuite
suite = unittest.TestLoader.loadTestsFromTestCase(self, testCaseClass)
self.suiteClass = unittest.TestLoader.suiteClass
return suite
这里可能缺少一个 try/except 块在之前和之后可能会使套件中的所有测试用例或其他东西失败。
【解决方案2】:
来自Python unittest documentation:
setUpClass():
在单个类运行测试之前调用的类方法。 setUpClass 以类作为唯一参数调用,并且必须装饰为 classmethod():
@classmethod
def setUpClass(cls):
...
2.7 版中的新功能。
tearDownClass():
在单个类中的测试运行后调用的类方法。 tearDownClass 以类作为唯一参数调用,必须装饰为 classmethod():
@classmethod
def tearDownClass(cls):
...