Class 与单元测试中的实例属性
Class vs Instance attribute in unit test
在单元测试中 class,
class Product:
def __init__(self, name, price):
self.name = name
self.price = price
设置 class 属性 (#1) 而不是实例属性 (#2) 的基本原理是什么? class 与静态属性与实例属性之间的区别对我来说很清楚(并且在许多其他 SO 帖子中都有说明),但是 pros/cons 或每个的用例并不是很明显。
(1)
import unittest
class TestProduct(unittest.TestCase):
@classmethod
def setUp(cls):
cls.product = Product("book", 30)
(2)
import unittest
class TestProduct(unittest.TestCase):
def setUp(self):
self.product = Product("book", 30)
顺便说一句,class 和实例初始化方法的正确名称是:
class TestProduct(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.product = Product("book", 30)
def setUp(self):
self.product = Product("book", 30)
不同之处在于 setUp
将针对 TestProduct
中的每个测试方法调用。它旨在重置可以通过某些测试更改的对象的值。另一方面,setUpClass
在 TestProduct
中的任何测试之前只被调用一次。它用于对在任何测试中都不会更改的对象进行昂贵的初始化。
考虑这个例子:
class TestProduct(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.list_a = []
def setUp(self):
self.list_b = []
def test_one(self):
self.assertFalse(self.list_b)
self.list_a.append(1)
def test_two(self):
self.assertFalse(self.list_a)
self.list_b.append(1)
test_two
如果在 test_one
之前运行就会成功,因为 class 属性 list_a
仍然是空的。但如果它在 test_one
之后运行,它将失败,因为 test_one
将值附加到共享 class 属性。
另一方面,test_one
将始终通过,因为即使 test_two
先运行,因为 test_one
会看到 setUp
在之前立即创建的新空列表test_one
被调用,而不是 test_two
修改的列表。
setUp
在 every 实例方法被调用之前被调用。 setUpClass
仅在定义 class 之后调用一次,但在调用任何测试之前调用。
在你的例子中,如果 Product
实例是不可变的或者没有测试方法修改实例,那么你使用哪个并不重要,因为每个测试都会看到相同的值,无论它是否定义在 setUp
或 setUpClass
。但是当共享 Product
实例可行时,setUpClass
比在每次测试之前重新创建相同的可变值更有效。
在单元测试中 class,
class Product:
def __init__(self, name, price):
self.name = name
self.price = price
设置 class 属性 (#1) 而不是实例属性 (#2) 的基本原理是什么? class 与静态属性与实例属性之间的区别对我来说很清楚(并且在许多其他 SO 帖子中都有说明),但是 pros/cons 或每个的用例并不是很明显。
(1)
import unittest
class TestProduct(unittest.TestCase):
@classmethod
def setUp(cls):
cls.product = Product("book", 30)
(2)
import unittest
class TestProduct(unittest.TestCase):
def setUp(self):
self.product = Product("book", 30)
顺便说一句,class 和实例初始化方法的正确名称是:
class TestProduct(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.product = Product("book", 30)
def setUp(self):
self.product = Product("book", 30)
不同之处在于 setUp
将针对 TestProduct
中的每个测试方法调用。它旨在重置可以通过某些测试更改的对象的值。另一方面,setUpClass
在 TestProduct
中的任何测试之前只被调用一次。它用于对在任何测试中都不会更改的对象进行昂贵的初始化。
考虑这个例子:
class TestProduct(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.list_a = []
def setUp(self):
self.list_b = []
def test_one(self):
self.assertFalse(self.list_b)
self.list_a.append(1)
def test_two(self):
self.assertFalse(self.list_a)
self.list_b.append(1)
test_two
如果在 test_one
之前运行就会成功,因为 class 属性 list_a
仍然是空的。但如果它在 test_one
之后运行,它将失败,因为 test_one
将值附加到共享 class 属性。
test_one
将始终通过,因为即使 test_two
先运行,因为 test_one
会看到 setUp
在之前立即创建的新空列表test_one
被调用,而不是 test_two
修改的列表。
setUp
在 every 实例方法被调用之前被调用。 setUpClass
仅在定义 class 之后调用一次,但在调用任何测试之前调用。
在你的例子中,如果 Product
实例是不可变的或者没有测试方法修改实例,那么你使用哪个并不重要,因为每个测试都会看到相同的值,无论它是否定义在 setUp
或 setUpClass
。但是当共享 Product
实例可行时,setUpClass
比在每次测试之前重新创建相同的可变值更有效。