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 中的每个测试方法调用。它旨在重置可以通过某些测试更改的对象的值。另一方面,setUpClassTestProduct 中的任何测试之前只被调用一次。它用于对在任何测试中都不会更改的对象进行昂贵的初始化。

考虑这个例子:

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 修改的列表。

setUpevery 实例方法被调用之前被调用。 setUpClass 仅在定义 class 之后调用一次,但在调用任何测试之前调用。

在你的例子中,如果 Product 实例是不可变的或者没有测试方法修改实例,那么你使用哪个并不重要,因为每个测试都会看到相同的值,无论它是否定义在 setUpsetUpClass。但是当共享 Product 实例可行时,setUpClass 比在每次测试之前重新创建相同的可变值更有效。