问题:用于多个测试的Unittest setUp / tearDown
在测试场景的开头/结尾是否触发了某个功能?在每次测试之前/之后都会触发setUp和tearDown函数。
我通常希望拥有:
class TestSequenceFunctions(unittest.TestCase):
def setUpScenario(self):
start() #launched at the beginning, once
def test_choice(self):
element = random.choice(self.seq)
self.assertTrue(element in self.seq)
def test_sample(self):
with self.assertRaises(ValueError):
random.sample(self.seq, 20)
for element in random.sample(self.seq, 5):
self.assertTrue(element in self.seq)
def tearDownScenario(self):
end() #launched at the end, once
目前,这些setUp和tearDown是单元测试,并且分散在我所有的场景中(包含许多测试),一个是第一个测试,另一个是最后一个测试。
回答 0
从2.7开始(根据文档),分别在给定类中的测试运行之前和之后获得,setUpClass
并tearDownClass
分别执行。或者,如果您在一个文件中有一组,则可以使用setUpModule
和tearDownModule
(文档)。
否则,最好的选择是创建自己的派生TestSuite并重写run()
。所有其他调用将由父级处理,运行会在父级run
方法的调用前后调用您的设置和拆卸代码。
回答 1
我有同样的情况,对我来说setUpClass和tearDownClass方法可以完美地工作
import unittest
class Test(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls._connection = createExpensiveConnectionObject()
@classmethod
def tearDownClass(cls):
cls._connection.destroy()
回答 2
对于python 2.5,以及在使用pydev时,这有点困难。似乎pydev并没有使用测试套件,而是找到所有单独的测试用例并分别运行它们。
我的解决方案是使用这样的类变量:
class TestCase(unittest.TestCase):
runCount = 0
def setUpClass(self):
pass # overridden in actual testcases
def run(self, result=None):
if type(self).runCount == 0:
self.setUpClass()
super(TestCase, self).run(result)
type(self).runCount += 1
使用此技巧,从此继承TestCase
(而不是从原始unittest.TestCase
)继承时,您还将继承runCount
0。然后在run方法中,runCount
检查并增加子测试用例的。此类的runCount
变量保留为0。
这意味着setUpClass
遗嘱每个类只能运行一次,而不是每个实例一次。
我还没有tearDownClass
方法,但是我想使用该计数器可能会有所作为。
回答 3
这是一个示例:3种测试方法访问一个共享资源,该资源一次创建,而不是每个测试一次。
import unittest
import random
class TestSimulateLogistics(unittest.TestCase):
shared_resource = None
@classmethod
def setUpClass(cls):
cls.shared_resource = random.randint(1, 100)
@classmethod
def tearDownClass(cls):
cls.shared_resource = None
def test_1(self):
print('test 1:', self.shared_resource)
def test_2(self):
print('test 2:', self.shared_resource)
def test_3(self):
print('test 3:', self.shared_resource)