94

我的 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 ---

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

4

8 回答 8

123

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

于 2013-01-13T17:21:48.747 回答
73

丹尼尔的回答是正确的,但是这里有一个例子可以避免我发现的一些常见错误,例如不调用when是(like in super()or )的子类。setUpClass()TestCaseunittest.TestCasedjango.testfalcon.testing

的文档setUpClass()没有提到你需要super()在这种情况下打电话。如果不这样做,您将收到错误,如相关问题所示。

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()
于 2015-12-03T12:01:04.183 回答
5

我正在使用 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 = TestThing.thing # ...but set on each test case instance

  def test_the_thing(self):
    self.assertTrue(self.thing is not None)
于 2020-03-06T01:32:55.260 回答
3

If you ended up here because of need to load some data for testing... then as far as you are using Django 1.9+ please go for 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') 
于 2019-01-04T17:48:12.037 回答
3

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)
于 2018-03-23T21:01:27.153 回答
2

不要尝试对 setUp 的调用进行重复数据删除,只需调用一次即可。

例如:

class MyClass(object):
    ...

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

_set_up()

这将在模块第一次加载时调用 _set_up()。我将它定义为模块级函数,但您同样可以将其设为 MyClass 的类方法。

于 2013-01-13T18:22:10.460 回答
2

将您想要设置的所有代码放在 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)

另一种可能性是有一个您在其中实例化的 Singleton 类setUp(),它只会运行__new__一次代码并为其余调用返回对象实例。请参阅:是否有一种简单、优雅的方式来定义单例?

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)

不过你的方法也行。

于 2015-02-19T13:46:57.337 回答
0

对于 python >3,您可以通过定义startTestRun, stopTestRunof来做到这一点unittest.TestResult class。回答https://stackoverflow.com/a/64892396/2679740

于 2020-11-18T11:59:05.273 回答