用于多个测试的Unittest setUp / tearDown


118

在测试场景的开头/结尾是否触发了某个功能?在每次测试之前/之后都会触发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是单元测试,并且分散在我所有的场景中(包含许多测试),一个是第一个测试,另一个是最后一个测试。


6
哪个版本?在Python 2.7中,已将unittest模块扩展为包括module_setup和module_teardown。
S.Lott

3
2.7还引入了setUpClass()和tearDownClass()类方法,这将使您可以在同一文件中拥有多个类,并具有各自的针对每个套房的设置和拆除功能。
Fafagrell 2011年

Answers:


132

从2.7开始(根据文档),分别在给定类中的测试运行之前和之后获得,setUpClasstearDownClass分别执行。或者,如果您在一个文件中有一组,则可以使用setUpModuletearDownModule文档)。

否则,最好的选择是创建自己的派生TestSuite并重写run()。所有其他调用将由父级处理,运行会在父级run方法的调用前后调用您的设置和拆卸代码。


71

我有同样的情况,对我来说setUpClass和tearDownClass方法可以完美地工作

import unittest

class Test(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls._connection = createExpensiveConnectionObject()

    @classmethod
    def tearDownClass(cls):
        cls._connection.destroy()

6
应该将其更新为可接受的答案,因为它显示了正确的示例,并且这些函数必须是类方法才能正常工作,在可接受的答案中未提及。
NuclearPeon '18

1

对于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)继承时,您还将继承runCount0。然后在run方法中,runCount检查并增加子测试用例的。此类的runCount变量保留为0。

这意味着setUpClass遗嘱每个类只能运行一次,而不是每个实例一次。

我还没有tearDownClass方法,但是我想使用该计数器可能会有所作为。


0

这是一个示例: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)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.