在 Python unittest 中 setUp()和 setUpClass()有什么区别?

在 Python unittest框架中,setUp()setUpClass()有什么不同?为什么要用一种方法而不是另一种方法来处理安装?

我想了解在 setUp()setUpClass()函数中,以及在 tearDown()tearDownClass()中,设置的哪一部分是完成的。

70376 次浏览

当类中有多个测试方法时,这种差异就会显现出来。setUpClasstearDownClass在整个类中运行一次; setUptearDown在每个测试方法之前和之后运行。

例如:

class Example(unittest.TestCase):
@classmethod
def setUpClass(cls):
print("setUpClass")


def setUp(self):
print("setUp")


def test1(self):
print("test1")


def test2(self):
print("test2")


def tearDown(self):
print("tearDown")


@classmethod
def tearDownClass(cls):
print("tearDownClass")

当您运行这个测试时,它会打印:

setUpClass
setUp
test1
tearDown
.setUp
test2
tearDown
.tearDownClass

(点(.)是测试通过时 unittest的默认输出。)观察到 setUptearDown出现在 test1 还有 test2之前和之后,而 setUpClasstearDownClass只出现一次,出现在整个测试病例的开始和结束。

在 Python unittest框架中,setUp()setUpClass()有什么不同?

主要的区别(正如 Benjamin Hodgson 在答案中指出的那样)是 setUpClass只被调用一次,而且是在所有测试之前,而 setUp是在每个测试之前立即被调用的。(注意: 这同样适用于其他 xUnit 测试框架中的等效方法,而不仅仅是 Python 的 unittest。)

来自 unittest 文件:

setUpClass()

运行单个类中的测试之前调用的类方法。SetUpClass 是以类作为唯一参数调用的,并且必须修饰为 classmethod () :

@classmethod
def setUpClass(cls):
...

以及:

setUp()

方法来准备测试夹具。在调用测试方法之前立即调用此方法; 除了 AssertionError 或 SkipTest 之外,此方法引发的任何异常都将被视为错误,而不是测试失败。默认实现不执行任何操作。

为什么要用一种方法而不是另一种方法来处理安装?

这部分问题还没有得到回答。根据我对 Gearon 的回答的评论,setUp方法用于 fixture 中所有测试都通用的元素(以避免在每个测试中重复该代码)。我发现这通常很有用,因为删除重复(通常)可以提高可读性并减少维护负担。

setUpClass方法适用于那些开销较大的元素,而这些元素只需要执行一次,比如打开数据库连接、在文件系统上打开一个临时文件、加载一个共享库以进行测试等等。在每个测试之前做这些事情会使测试套件变慢太多,所以我们只在所有测试之前做一次。这是测试独立性的轻微降低,但在某些情况下是必要的优化。可以说,在单元测试中不应该做这样的事情,因为通常可以在不使用真实内容的情况下模拟数据库/文件系统/库/其他内容。因此,我发现很少需要 setUpClass。但是,当需要测试上面的例子(或类似的例子)时,它是有用的。

如上所述,setup ()和 teardown ()将在每次测试之后和之前运行。但是 SetupClass ()和 TearDownClass ()对于整个类只运行一次。