关于python:对一组自动测试只运行一次安装程序

Run setUp only once for a set of automated tests

我的python版本是2.6。

我只想执行一次测试设置方法,因为我在那里做了所有测试都需要的事情。

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

1
2
3
4
5
6
7
8
9
10
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)

输出:

1
2
3
4
5
6
7
8
9
10
11
False

True

--- Test 1 ---

False

True

--- Test 2 ---

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


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


丹尼尔的回答是正确的,但这里有一个例子来避免我发现的一些常见错误,例如当TestCaseunittest.TestCase的一个子类(如django.testfalcon.testing)时,不在setUpClass()中调用super())。

setUpClass()的文档没有提到在这种情况下需要调用super()。如果不这样做,您将得到一个错误,如这个相关问题所示。

1
2
3
4
5
6
7
8
9
10
11
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()


如果因为需要加载一些数据进行测试而在这里结束…然后,只要您使用django 1.9+,请转到SETUPTESTDATA:

1
2
3
4
5
6
7
8
9
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')

不要试图消除对安装程序的调用,只需调用一次。

例如:

1
2
3
4
5
6
7
class MyClass(object):
    ...

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

_set_up()

这将在模块首次加载时调用_set_up()。我已经将它定义为一个模块级函数,但您也可以将它设置为MyClass的类方法。


安装完成是一个类变量,而不是一个实例变量。

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

self.setup_done

但您需要将其作为类变量引用:

mySelTest.setup_done

这是正确的代码:

1
2
3
4
5
6
7
8
9
10
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)

把你想要设置的所有代码放在myselest之外。

1
2
3
4
5
6
7
8
9
10
11
12
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()中实例化的单例类,它只运行一次__new__代码,并返回其余调用的对象实例。看:有没有一个简单,优雅的方式来定义单件?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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)

不过,你的方法也很管用。