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

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值