对于一组自动化测试,仅运行setUp一次

时间:2013-01-13 17:11:03

标签: python unit-testing

我的Python版本是2.6。

我只想执行一次测试setUp方法,因为我在那里做了所有测试都需要的东西。

我的想法是创建一个布尔变量,在第一次执行后将设置为'true',然后禁用对setup方法的多次调用。

class mySelTest(unittest.TestCase):
    setup_done = False

    def setUp(self):
        print str(self.setup_done)
            
        if self.setup_done:
            return
        self.setup_done = True
        print str(self.setup_done)

输出:

False

True

--- Test 1 ---

False

True

--- Test 2 ---

为什么这不起作用?我错过了什么吗?

8 个答案:

答案 0 :(得分:88)

您可以使用setUpClass来定义每个测试套件只运行一次的方法。

答案 1 :(得分:49)

Daniel's answer是正确的,但这里有一个示例可以避免我发现的一些常见错误,例如super() setUpClass()TestCase的子类时unittest.TestCase没有调用django.test {1}}(例如falcon.testingsuper())。

setUpClass()的文档未提及在这种情况下您需要致电class SomeTest(TestCase): def setUp(self): self.user1 = UserProfile.objects.create_user(resource=SomeTest.the_resource) @classmethod def setUpClass(cls): """ get_some_resource() is slow, to avoid calling it for each test use setUpClass() and store the result as class variable """ super(SomeTest, cls).setUpClass() cls.the_resource = get_some_resource() 。如果不这样做,您将收到错误,如this related question中所示。

{{1}}

答案 2 :(得分:2)

请勿尝试重复调用setUp,只需调用一次。

例如:

class MyClass(object):
    ...

def _set_up():
    code to do one-time setup

_set_up()

首次加载模块时,这将调用_set_up()。我已经将它定义为模块级函数,但你可以同样使它成为MyClass的类方法。

答案 3 :(得分:2)

如果由于需要加载一些数据进行测试而最终来到这里... 那么就您使用Django 1.9+而言,请继续使用setUpTestData

class MyTests(TestCase):

    @classmethod
    def setUpTestData(cls):
        # Set up data for the whole TestCase
        cls.foo = Foo.objects.create(bar="Test")

    def test1(self):
        self.assertEqual(self.foo.bar, 'Test') 

答案 4 :(得分:1)

将您想要设置的所有代码放在mySelTest之外。

setup_done = False

class mySelTest(unittest.TestCase):

    def setUp(self):
        print str(setup_done)

        if setup_done:
            return

        setup_done = True
        print str(setup_done)

另一种可能性是让你在setUp()中实例化一个Singleton类,它只运行一次__new__代码并返回其余调用的对象实例。 请参阅:Is there a simple, elegant way to define singletons?

class Singleton(object):
    _instance = None
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(Singleton, cls).__new__(
                            cls, *args, **kwargs)
            # PUT YOUR SETUP ONCE CODE HERE!
            cls.setUpBool = True

        return cls._instance

class mySelTest(unittest.TestCase):

    def setUp(self):
        # The first call initializes singleton, ever additional call returns the instantiated reference.
        print(Singleton().setUpBool)

你的方式也有效。

答案 5 :(得分:1)

setup_done是一个类变量,而不是实例变量。

您将其作为实例变量引用:

self.setup_done

但是你需要将它作为一个类变量引用:

mySelTest.setup_done

以下是更正后的代码:

class mySelTest(unittest.TestCase):
    setup_done = False

    def setUp(self):
        print str(mySelTest.setup_done)

        if mySelTest.setup_done:
            return
        mySelTest.setup_done = True
        print str(mySelTest.setup_done)

答案 6 :(得分:1)

我正在使用Python 3,发现cls方法中也提供了setup引用,因此可以进行以下工作:

class TestThing(unittest.TestCase):

  @classmethod
  def setUpClass(cls):
    cls.thing = Thing() # the `thing` is only instantiated once

  def setup(self):
    self.thing = cls.thing # ...but set on each test case instance

  def test_the_thing(self):
    self.assertTrue(self.thing is not None)

答案 7 :(得分:0)

对于python> 3,您可以通过定义startTestRun中的stopTestRununittest.TestResult class来实现。回答https://stackoverflow.com/a/64892396/2679740