关于python:unittest的tearDown和setUp不会以相同的方式更新属性

unittest's tearDown and setUp don't update the properties the same way

本问题已经有最佳答案,请猛点这里访问。

我正在编写一些单元测试,在每次测试之前我都有一些准备工作要做,在每次测试之后我都要撤消这些测试。因此,我使用设置来准备它们,使用列表列出我已经执行的操作,在拆卸过程中,我撤消所述列表中列出的操作并清除列表。

但是当我到达下面的测试时,列表的状态与TearDown离开它的状态不同,而是在上一个设置离开它的状态下。感觉很奇怪。我在这里做错什么了吗?

下面是一个不带我的业务代码的简短示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class MyTest(TestCase):
    val = []

    def setUp(self):
        super().setUp()
        print("before setup, val = {}".format(self.val))

        self.val.append("AAA")

        print("after setup: val = {}".format(self.val))

    def tearDown(self):
        super().tearDown()
        print("before teardown, val = {}".format(self.val))

        self.val = []  # or whatever

        print("after teardown, val = {}".format(self.val))

    def test_one(self):
        assert True

    def test_two(self):
        assert True

将返回

1
2
3
4
5
6
7
8
9
10
before start, val = []
after setup: val = ['AAA']
before teardown, val = ['AAA']
after teardown, val = []
.
before start, val = ['AAA']  # <- why is this not []??
after setup: val = ['AAA', 'AAA']
before teardown, val = ['AAA', 'AAA']
after teardown, val = []
.

第二个测试的设置不应该找到.val=[]?我不知道为什么以前的眼泪似乎没有改变它的价值。有什么想法吗?


MyTest.val替换self.valval是一个类级变量,不是一个对象级变量。另一种方法是在setUp中初始化self.val,而不是将其设为类级变量。


val是一个类属性。当你这样做的时候:

1
self.val.append("AAA")

这将修改val的类版本。但是,当您这样做时:

1
self.val = []

创建名为val的实例属性,并将其设置为空列表。你真正想做的是:

1
self.val[:] = []

这将修改可变类属性val