Python setUp()
框架中setUpClass()
和unittest
之间有什么区别?为什么设置应该用一种方法处理另一种方法?
我想了解setUp()
和setUpClass()
函数以及tearDown()
和tearDownClass()
中的设置部分是什么。
答案 0 :(得分:107)
当您的班级中有多个测试方法时,差异就会显现出来。 setUpClass
和tearDownClass
为整个班级运行一次; setUp
和tearDown
在每种测试方法之前和之后运行。
例如:
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
的默认输出。)观察setUp
和tearDown
出现在{之前和之后{ {1}} 和 test1
,而test2
和setUpClass
只出现一次,在整个测试用例的开头和结尾。
答案 1 :(得分:6)
setUp()
框架中setUpClass()
和unittest
有什么区别?主要区别(如本杰明·霍奇森(Benjamin Hodgson)的回答中所述)是,setUpClass
仅在所有测试之前被调用一次,而setUp
在每个测试之前被调用。 (注意:这同样适用于其他xUnit测试框架中的等效方法,而不仅仅是Python的unittest
。)
来自unittest
documentation:
setUpClass()
在运行单个类中的测试之前调用的类方法。使用类作为唯一参数调用setUpClass,并且必须将其装饰为classmethod():
@classmethod
def setUpClass(cls):
...
和:
setUp()
调用该方法准备测试夹具。在调用测试方法之前立即调用该方法。除了AssertionError或SkipTest之外,此方法引发的任何异常都将被视为错误而不是测试失败。默认实现不执行任何操作。
这部分问题尚未回答。根据我对Gearon回答的评论,setUp
方法适用于所有测试通用的灯具元素(以避免在每个测试中重复该代码)。我发现这样做通常很有用,因为删除重复项通常可以提高可读性并减轻维护负担。
setUpClass
方法用于只需要执行一次的昂贵元素,例如打开数据库连接,打开文件系统上的临时文件,加载用于测试的共享库等。每次测试之前的事情会使测试套件减慢太多,因此我们在所有测试之前只做一次。测试的独立性略有下降,但在某些情况下是必要的优化。可以说,在单元测试中不应该这样做,因为通常可以在不使用真实内容的情况下模拟数据库/文件系统/库/任何东西。因此,我发现几乎不需要setUpClass
。但是,当需要测试上述示例(或类似示例)时,这很有用。
答案 2 :(得分:0)
阅读问题和接受的答案后,我认为可以做一些补充。
问:为什么设置要用一种方法而不是另一种方法?
答:这是因为测试方法可能需要初步的测试,而初步测试因测试方法而异。
例如,以https://www.tutorialspoint.com/unittest_framework/unittest_framework_api.htm中的以下代码为示例:
import unittest
class simpleTest2(unittest.TestCase):
def setUp(self):
self.a = 10
self.b = 20
name = self.shortDescription()
if name == "add":
self.a = 10
self.b = 20
print name, self.a, self.b
if name == "sub":
self.a = 50
self.b = 60
print name, self.a, self.b
def tearDown(self):
print '\nend of test',self.shortDescription()
def testadd(self):
"""add"""
result = self.a+self.b
self.assertTrue(result == 30)
def testsub(self):
"""sub"""
result = self.a-self.b
self.assertTrue(result == -10)
if __name__ == '__main__':
unittest.main()
方法testadd
和testsub
需要不同的输入,我们可以分别在setUp
方法中设置输入的值。