美文网首页
Unittest-测试固件:初始化与清理

Unittest-测试固件:初始化与清理

作者: 猫与测试 | 来源:发表于2019-11-12 18:54 被阅读0次

    unittest 提供了针对测试方法、测试类、测试模块三种范围的测试固件,每个范围都有初始化和清理两种固件。

    测试方法

    setUp() 和 tearDown() 两个方法是针对测试用例方法级别的测试固件。

    在当前测试类中重写这两个方法,当前测试类中的所有测试方法都会执行这两个测试固件。

    在每个测试方法运行之前运行 setUp(), 在每个测试方法运行之后运行 tearDown()。注意是每个测试方法。
    这就类似某些框架中提供的钩子hook函数。

    我们把前面的案例改造一下,加上了 setUp() 和 tearDown(),为了方便观察,每个用例执行了一条打印语句:

    import unittest
    
    def add(a, b):
        return a+b
    
    
    class TestAdd(unittest.TestCase):
        def setUp(self):
            print('\n**********执行初始化方法************')
            
        def tearDown(self):
            print('\n**********执行清理方法************')
            
        def test_add_int(self):
            '''测试int相加'''
            result = add(5, 100)
            print('用例1结果:', result)
            self.assertEqual(result, 105, '整数相加错误')
            
        def test_add_str(self):
            '''测试str相加'''
            result = add('5', '6')
            print('用例2结果:', result)
            self.assertEqual(result, '56', '字符串相加错误')
            
        def test_add_list(self):
            result = add(['1', '2'], ['a', 'b'])
            print('用例3结果:', result)
            self.assertEqual(result, ['1','2','a','b'], '列表相加错误')
    
    if __name__ == "__main__":
        unittest.main()
    

    运行看看结果:

    ...
    **********执行初始化方法************
    用例1结果: 105
    
    **********执行清理方法************
    
    **********执行初始化方法************
    用例3结果: ['1', '2', 'a', 'b']
    
    **********执行清理方法************
    
    **********执行初始化方法************
    用例2结果: 56
    
    **********执行清理方法************
    
    ----------------------------------------------------
    Ran 3 tests in 0.001s
    
    OK
    

    可以看到结果中,setUp() 方法执行了 3 次,而 tearDown() 方法也执行了 3 次。

    当然,这里为了演示只是写了一条打印语句,具体初始化和清理方法应该写哪些代码,取决于你的测试策略。

    测试类

    接下来,我们看看基于测试类的固件 setUpClass() 和 tearDownClass() ,这两个方法必须作为类方法来定义。

    运行效果为每个测试类中的第一个测试方法开始运行之前与进行 setUpClass() ,在最后一个测试方法运行之后运行 tearDownClass() 。

    也就是说,每个测试类,测试固件只会运行一次。

    同样,改造一下之前的案例。

    import unittest
    
    def add(a, b):
        return a+b
    
    class TestAdd(unittest.TestCase):
        @classmethod    # 类方法需要加上classmethod装饰器
        def setUpClass(cls):   # => 第一个参数为cls
            print('\n*******执行类级别的初始化方法setUpClass*********')
    
        @classmethod
        def tearDownClass(cls):
            print('\n*******执行类级别的清理方法tearDownClass********')
    
        def test_add_int(self):
            '''测试int相加'''
            result = add(5, 100)
            print('用例1结果:', result)
            self.assertEqual(result, 105, '整数相加错误')
    
        def test_add_str(self):
            '''测试str相加'''
            result = add('5', '6')
            print('用例2结果:', result)
            self.assertEqual(result, '56', '字符串相加错误')
    
        def test_add_list(self):
            result = add(['1', '2'], ['a', 'b'])
            print('用例3结果:', result)
            self.assertEqual(result, ['1','2','a','b'], '列表相加错误')
    
    if __name__ == "__main__":
        unittest.main()
    

    注意在写法上:

        @classmethod    # 类方法需要加上classmethod装饰器
        def setUpClass(cls):   # => 第一个参数为cls
            print('\n*******执行类级别的初始化方法setUpClass*********')
    

    setUpClass(cls) 必须要写为 类方法,所以必须要加上classmethod装饰器,并且第一个参数使用 cls

    运行结果如下:

    ...
    **********执行类级别的初始化方法setUpClass************
    用例1结果: 105
    用例3结果: ['1', '2', 'a', 'b']
    用例2结果: 56
    
    **********执行类级别的清理方法tearDownClass************
    
    ----------------------------------------------------------------------
    Ran 3 tests in 0.000s
    
    OK
    

    可以从结果中看到类测试固件只会在每个测试类中执行一次。

    模块级别

    模块级别指的是文件级别。Python 中文件即模块,所以你可以理解为每个文件只运行一次 ,不管你的这个测试文件中有多少的测试类和测试方法。

    注意,测试模块(也就是测试文件)一定要包含test字样。虽然不是必须,但是会影响一些工具的默认测试模块的查找功能。

    实现模块级别的固件,是使用 setUpModule() 和 tearDownModule() 两个函数(注意是函数,不是方法,写在类外面),函数的位置不重要,只要是在当前测试文件中实现这两个方法即可。

    为了更好的演示,我把之前的示例拆为了两个类,用例方法不变。

    import unittest
    
    def setUpModule():  # => 初始化固件
        print('\n********执行模块级别的初始化方法setUpModule**********')
    
    def tearDownModule():  # => 清理固件
        print('\n********执行模块级别的初始化方法tearDownModule**********')
    
    def add(a, b):  
        return a+b
    
    class TestAddOne(unittest.TestCase):
    
        def test_add_int(self):
            '''测试int相加'''
            result = add(5, 100)
            print('用例1结果:', result)
            self.assertEqual(result, 105, '整数相加错误')
    
        def test_add_str(self):
            '''测试str相加'''
            result = add('5', '6')
            print('用例2结果:', result)
            self.assertEqual(result, '56', '字符串相加错误')
    
    class TestAddTwo(unittest.TestCase):
        def test_add_list(self):
            result = add(['1', '2'], ['a', 'b'])
            print('用例3结果:', result)
            self.assertEqual(result, ['1','2','a','b'], '列表相加错误')
    
    if __name__ == "__main__":
        unittest.main()
    

    查看运行结果:

    ...
    ********执行模块级别的初始化方法setUpModule**********
    用例1结果: 105
    用例2结果: 56
    用例3结果: ['1', '2', 'a', 'b']
    ********执行模块级别的初始化方法tearDownModule**********
    ----------------------------------------------------------------------
    Ran 3 tests in 0.000s
    
    OK
    

    针对模块的测试固件每个文件只运行一次。

    相关文章

      网友评论

          本文标题:Unittest-测试固件:初始化与清理

          本文链接:https://www.haomeiwen.com/subject/mghgbctx.html