test fixture(测试固件、测试夹具、测试脚手架)
如果多个测试在执行前具有相同的初始化操作,或者执行后要做相同的清理工作,就可以把这些相同的动作提取出来放到一个专门的函数中。unittest提供了固定命名的方法用于进行这些初始化或清理的工作,在测试执行前和后,会由unittest自动去调用这两个方法。这种设计结构称之为 test fixture,翻译为测试固件或测试夹具。
- 初始化操作如:建立数据库连接、打开某文件 。。。
- 清理的操作如:断开数据库连接、关闭某文件 。。。
官方文档引用:unittest --- 单元测试框架 — Python 3.11.8 文档
Tests can be numerous, and their set-up can be repetitive. Luckily, we can factor out set-up code by implementing a method called setUp(), which the testing framework will automatically call for every single test we run
可能同时存在多个前置操作相同的测试,我们可以把测试的前置操作从测试代码中拆解出来,并实现测试前置方法 setUp() 。在运行测试时,测试框架会自动地为每个单独测试调用前置方法。
Similarly, we can provide a tearDown() method that tidies up after the test method has been run
相似的,我们提供了一个 tearDown() 方法在测试方法运行后进行清理工作。
Such a working environment for the testing code is called a test fixture. A new TestCase instance is created as a unique test fixture used to execute each individual test method. Thus setUp(), tearDown(), and __init__() will be called once per test.
这样的一个测试代码运行的环境被称为 test fixture 。一个新的 TestCase 实例作为一个测试脚手架,用于运行各个独立的测试方法。在运行每个测试时,setUp() 、tearDown() 和 __init__() 会被调用一次。
为了应对不同级别的操作,Unittest 提供了一套方法分别完成各级别前置初始化(setUp)和后置清理(tearDown)的工作:
- setUp():方法级别。在每个测试方法执行前被调用。
- tearDown():方法级别。在每个测试方法执行后被调用。
- setupClass():类级别。在每个测试用例执行前被调用,只会被执行一次。注意,要定义为 “类方法 @classmethod” 形式。
- tearDownClass():类级别。在每个测试用例执行后被调用,只会被执行一次。注意,要定义为 “类方法 @classmethod” 形式。
- setupModule():模块级别。在每个模块执行前被调用,只会被执行一次。
- teardownModule():模块级别。在每个模块执行后被调用,只会被执行一次。
举例:
import unittest
def setUpModule():
print("\n~~~~~~ 在每个模块运行前,进行初始化工作。~~~~~~")
def tearDownModule():
print("\n~~~~~~ 在每个模块运行后,进行初始化工作。~~~~~~")
class TestLab(unittest.TestCase):
@classmethod
def setUpClass(cls):
print("\n====== 在每个类运行前,进行初始化工作。======")
@classmethod
def tearDownClass(cls):
print("\n====== 在每个类运行后,进行清理的工作。======")
def setUp(self):
print("\n在每个测试方法运行前,进行初始化工作。")
def tearDown(self):
print("在每个测试方法运行后,进行清理的工作。")
def test_method_01(self):
print(f"测试方法:test_method_01")
self.assertEqual(1, 1)
if __name__ == '__main__':
unittest.main(verbosity=2)
执行结果:
从源码中也可见其调用次序:
注意:
- 若 setUp() 方法引发异常,测试框架会认为测试发生了错误,因此后续的测试方法不会被运行。
- 若 setUp() 成功运行,无论测试方法是否成功,都会运行 tearDown()。
- 如果在 setUpClass 中引发了异常,则类中的测试将不会被运行,并且 tearDownClass 也不会被运行
- 如果在 setUpModule 中引发了异常,则模块中的任何测试都将不会被运行,并且 tearDownModule 也不会被运行。