一、unittest介绍与使用
1.作用
用于单元测试(功能函数,类)、用例的管理、用例的加载、用例的执行、测试报告的生成。
2.组件
TestCase:定义测试用例
TestSuite:测试套件,用于管理测试用例
TestRunner:运行测试用例
TestLoader:加载测试用例
Fixture:想当于钩子,用户测试用例执行前后进行执行。
3.为什么要使用Unittest框架?
能够组织多个用例去执行
提供丰富的断言方法
能够生成测试报告(由于生成的测试报告简陋,我们选择其他插件实现)
4.Fixture
Fixture是一个概述,对一个测试用例环境的初始化和销毁就是一个Fixture。以开发视角去理解,Fixture就像是Flask框架中的钩子,特定的方法,在测试用例执行前后进行执行。
Fixture存在控制级别:不同的级别决定了执行的作业范围和时机
方法级别:在执行测试类中的每一个测试用例之前,都会执行一遍setUp()方法,执行完每一条测试用例,都会执行一遍tearDown()方法。
类级别:在整个测试类里面所有的测试用例执行之前,执行一次setUpClass(cls),所有的用例执行完之后,统一执行一次tearDownClass(cls) 。
模块级别:
-初始化(前置处理):def setUpModule() --> 首先自动执行
-销毁(后置处理):def tearDownModule() --> 最后自动执行
运行于整个模块的始末,即:整个模块只会运行一次 setUpModule 和 tearDownModule
5.运行用例
首先在pycharm中新建文件夹及文件,如图:
在mytest文件中,用Fixture方法级别写入:
# 导包
import unittest
# 待测函数
def two_he(a,b):
return a + b
# 测试类:方法-->测试用例
# 注意事项:
# -测试类,必须继承unittest.TestCase
# -测试用例:就是方法,方法必须以test开头
class BdTestClass(unittest.TestCase):
def setUp(self):
print("sutup方法执行啦!")
print("test_1")
def tearDown(self):
print("tearDown方法执行啦!")
print("test_2")
# 测试用例
def test_1(self):
# 调用待测函数
two_he(1,2)
def test_2(self):
two_he(7,5)
在two文件中写入:
# 导包
import unittest
# 待测函数
def th_he(a,b,c):
return a + b
# 测试类:方法-->测试用例
# 注意事项:
# -测试类,必须继承unittest.TestCase
# -测试用例:就是方法,方法必须以test开头
class ShTestClass(unittest.TestCase):
# 测试用例
def test_1(self):
# 调用待测函数
th_he(1,2,3)
def test_2(self):
th_he('abc',5,6)
最后在main函数中写入:
# 1、导包
# 2、创建测试类,写测试用例
# 3、加载用例:
# 3.1 实例化一个测试套件用于加载测试用例:suite = unittest.TestSuite()
# 3.2 加载用例
# -addTest(模块名.类名("方法名"))
# -addTest(unittest.makeSuite(mytest.BdTestClass))
# -suite = unittest.TestLoader().discover('路径','文件名+通配符')
# 4、执行测试用例
# 4.1 借助一个runner对象:runner = unittest.TextTestRunner()
# 4.2 runner对象调用run方法,传递测试套件(suite)来执行
import unittest
from project03.myinfrom.case import mytest
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(mytest.BdTestClass))
# suite = unittest.TestLoader().discover('D:/p6课堂练习/project03/myinfrom/case','*test.py')
runner = unittest.TextTestRunner()
runner.run(suite)
方法级别运行结果:
在mytest文件中,用Fixture类级别写入:
# 导包
import unittest
# 待测函数
def two_he(a,b):
return a + b
# 测试类:方法-->测试用例
# 注意事项:
# -测试类,必须继承unittest.TestCase
# -测试用例:就是方法,方法必须以test开头
class BdTestClass(unittest.TestCase):
# def setUp(self):
# print("sutup方法执行啦!")
# print("test_1")
#
# def tearDown(self):
# print("tearDown方法执行啦!")
# print("test_2")
@classmethod
def setUpClass(cls):
print('setUpclass running!')
@classmethod
def tearDownClass(cls):
print('tearDownclass running!')
# 测试用例
def test_1(self):
# 调用待测函数
two_he(1,2)
def test_2(self):
two_he(7,5)
类级别用不到two文件
最后在main函数中写入:
# 1、导包
# 2、创建测试类,写测试用例
# 3、加载用例:
# 3.1 实例化一个测试套件用于加载测试用例:suite = unittest.TestSuite()
# 3.2 加载用例
# -addTest(模块名.类名("方法名"))
# -addTest(unittest.makeSuite(mytest.BdTestClass))
# -suite = unittest.TestLoader().discover('路径','文件名+通配符')
# 4、执行测试用例
# 4.1 借助一个runner对象:runner = unittest.TextTestRunner()
# 4.2 runner对象调用run方法,传递测试套件(suite)来执行
import unittest
from project03.myinfrom.case import mytest
# suite = unittest.TestSuite()
# suite.addTest(unittest.makeSuite(mytest.BdTestClass))
suite = unittest.TestLoader().discover('D:/p6课堂练习/project03/myinfrom/case','*test.py')
runner = unittest.TextTestRunner()
runner.run(suite)
类级别运行结果为:
6.总结:
二、Unittest断言、参数化与跳过操作
Unittest常用断言:
使用方式:断言已经在unittest.TestCase中定义好了,而且我们自定义的测试类已经继承了TestCase所以在测试方法中直接即可。
举例:在上述用例中的mytest中写入:
# 导包
import unittest
# 待测函数
def two_he(a,b):
return a + b
# 测试类:方法-->测试用例
# 注意事项:
# -测试类,必须继承unittest.TestCase
# -测试用例:就是方法,方法必须以test开头
class BdTestClass(unittest.TestCase):
# def setUp(self):
# print("sutup方法执行啦!")
# print("test_1")
#
# def tearDown(self):
# print("tearDown方法执行啦!")
# print("test_2")
@classmethod
def setUpClass(cls):
print('setUpclass running!')
@classmethod
def tearDownClass(cls):
print('tearDownclass running!')
# 测试用例
def test_1(self):
# 调用待测函数
ret = two_he(1,2)
self.assertEqual(3,ret,msg="结果不等于3")
def test_2(self):
ret = two_he(9,5)
self.assertEqual(15, ret, msg="结果不等于14")
运行结果:
参数化
通过我们之间对一个两个数加法和函数的验证,我们会发现,在编写测试用例的过程中,(1,3),(4,3),(1,2)等参数中,每一个参数都要写一条用例,且用例代码也是一样形式的,这就造成了代码冗余,所以需要进行参数化,提高用例的复用性,通过参数化的方式来传递数据,从而实现数据和脚本分离,并且可以实现用例的重复执行。
unittest测试框架,本身不支持参数化,但是可以通过安装unittest扩展插件parameterized来实现。
安装:pip install parameterized
使用:在mytest中写入:
# 导包
import json
import unittest
from parameterized import parameterized
# 待测函数
def two_he(a,b):
return a + b
def build_data():
with open('./data.json','r',encoding='utf-8') as f:
content = f.read()
d = [(i['x'],i['y'],i['exp']) for i in json.loads(content)]
return d
class BdTestClass(unittest.TestCase):
# 测试用例
@parameterized.expand(build_data())
def test_1(self,x,y,exp):
# 调用待测函数
ret = two_he(x,y)
self.assertEqual(exp,ret,msg="结果不等于6")
写入data.json文件:
[
{"x": 1,"y": 2,"exp": 3},
{"x": 1,"y": 3,"exp": 4},
{"x": 1,"y": 5,"exp": 7},
{"x": 2,"y": 2,"exp": 4}
]
最后在主函数中写入:
import unittest from case import mytest suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(mytest.BdTestClass)) runner = unittest.TextTestRunner() runner.run(suite)
运行结果为:



