我尝试用 Nose 测试 但是当我运行下面的测试用例时
import unittest
class TestSuite(unittest.TestCase):
b = []
def setUp(self):
self.b.extend([10, 20])
def tearDown(self):
self.b = []
def test_case_1(self):
self.b.append(30)
assert len(self.b) == 3
assert self.b == [10, 20, 30]
def test_case_2(self):
self.b.append(40)
assert len(self.b) == 3
assert self.b == [10, 20, 40]
但是所有的测试用例都没有通过
$> nosetest test_module.py
.F
======================================================================
FAIL: test_case_2 (test_module2.TestSuite)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/knt/test_module2.py", line 19, in test_case_2
assert len(self.b) == 3
AssertionError
----------------------------------------------------------------------
Ran 2 tests in 0.001s
FAILED (failures=1)
发生了什么???我预计在运行 test_case_1 之后,会调用 tearDown,所以 self.b 是 []。因此,对于下一个测试用例 test_case_2,setUp 运行并且 self.b 是 [10, 20]。
但实际上,在 setUp 处 self.b 的值是 [10, 20, 30]。
我不知道为什么。我认为 self.b = [] 语句一定有问题。
有什么相关的提示吗? 我仍然没有弄明白,但我找到了修复这个错误的方法。只需将 self.b = [] 更改为 del self.b[:]。
谁能帮我找出问题所在? 非常感谢。
请您参考如下方法:
据我所知,问题可能与 unitests 的工作方式以及类字段在 python 中的工作方式有关,这里是一个简单的测试:
class A:
b = []
def reset(self):
self.b = []
a = A()
a.b.append(3) # we are actually accessing the class variable here
print A.b is a.b # True
print a.b # [3] same here
a.reset() # We just hid the class variable with our own which points to []
print A.b is a.b # False as expected.
print a.b # [] we think its being clear but rather we are using our own not the class variable
b = A()
print b.b # [3] b here is using the class that a previously modified but is no longer pointing to
print b.b is A.b # True
# Also note
c = A()
d = A()
print c.b is d.b # True, since both are using the same class variable.
我认为 unittest 多次创建对象,为每个测试函数创建对象,触发访问类变量的设置,测试运行,调用简单隐藏它的拆解,创建另一个对象,调用访问相同的设置前一个对象修改的类变量,自从它被拆除后就没有影响,它只是创建了一个绑定(bind)到自身的新实例,隐藏了类版本。
我们总是使用 self 在 __init__ 中声明成员字段。
def __init__(self):
self.b = []
这样每个实例都会有自己的副本,虽然我们不能在这里这样做,因为我们继承自 unittest.TestCase 这就是为什么我们有 setUp
import unittest
class TestSuite(unittest.TestCase):
def setUp(self):
self.b = [10, 20]
def tearDown(self):
self.b = []
def test_case_1(self):
self.b.append(30)
assert len(self.b) == 3
assert self.b == [10, 20, 30]
def test_case_2(self):
self.b.append(40)
assert len(self.b) == 3
assert self.b == [10, 20, 40]
