文章目录
定义
框架framework,是用于解决某一类事情的功能集合,使用时需要按照框架规定去书写代码。
UnitTest框架,是python自带的单元测试框架,无需安装,可用于单元测试,第三方框架则需先安装后使用。
开发人员使用UnitTest进行单元测试,测试人员使用UnitTest来管理运行多个测试用例。
作用
1、自动化执行用例
2、提供丰富的断言方法,让程序代替人工判断结果是否符合预期
3、生成测试报告
核心要素
TestCase
测试用例,是UnitTest框架的组成部分,而非测试时使用的用例,是框架中最核心的模块。一个TestCase即一个代码文件,需按照标识符规则命名,可在开头说明用例测试目的。实际使用时通常将所有测试用例文件放在单独的目录中。
# 1、导包
import unittest
# 2、自定义测试类,继承TestCase类
class TestDemo(unittest.TestCase):
# 3、写测试方法即用例代码,需要test开头
# 因为unittest.main()的testMethodPrefix的值为'test'
# 4、执行用例
# a.光标定位到类名后执行,执行类中所有方法
# b.光标定位到方法名后执行,执行当前方法
如何用例执行失败,按照以下排查:
1、文件命名是否规范
2、测试方法命名是否规范
3、代码执行无结果可能是此前作为python文件运行过,可重建文件或删除运行方式
TestSuite
测试套件,管理、打包、组装多个测试用例
TestRunner
测试运行,运行测试套件
# 1、导包
import unittest
# 2、实例化套件对象
suite=unittest.TestSuite()
# 3、使用套件对象添加用例方法
# a.套件对象.addTest(测试类名('方法名')),一次只能添加一个方法
suite.addTest(TestDemo1('testMethod1'))
suite.addTest(TestDemo1('testMethod2'))
suite.addTest(TestDemo2('testMethod1'))
suite.addTest(TestDemo2('testMethod2'))
# b.套件对象.addTest(unittest.makeSuite(测试类名)),添加测试类的所有方法
# 需要导入TestDemo from ... import TestDemo
suite.addTest(unittest.makeSuite(TestDemo1))
suite.addTest(unittest.makeSuite(TestDemo2))
# 4、实例化运行对象
runner=unittest.TextTestRunner()
# 5、使用运行对象执行套件对象,运行对象.run(套件对象)
runner.run(suite)
TestLoader
测试加载,对测试套件功能的补充,当测试用例文件很多时使用。
# 1、导包
import unittest
# 2、实例化加载对象并添加用例
# 实例化测试加载对象得到的是suite对象
# 用例路径通常使用相对路径./,用例文件名可使用通配符*
suite=unittest.TestLoader().discover('用例所在路径','用例文件名')
# 也可以使用默认的加载对象
suite=unittest.defaultTestLoader.discover('用例所在路径','用例文件名')
# 3和4也可合为一步,少一行代码
# 3、实例化运行对象
runner=unittest.TextTestRunner()
# 4、使用运行对象执行套件对象,运行对象.run(套件对象)
runner.run(suite)
Fixture
测试夹具,写在测试用例中的代码结构,每个方法执行前后都会执行的内容,方法级别和类级别前后执行的内容,并不是一定要同时出现的,根据实际需要使用。
方法级别
每个测试方法执行前后都会自动执行的结构。
# 方法执行前
def setUp(self):
pass
# 方法执行后
def tearDown(self):
pass
类级别
每个测试类中所有方法执行前后都会自动执行的结构。
# 需要写在类的外边,直接定义函数即可
# 代码文件执行前
@classmethod
def setUpModule():
pass
#代码文件执行后
@classmethod
def tearDownModule():
pass
模块级别
每个代码文件执行前后都会自动执行的结构。
# 方法执行前
def setUp(self):
pass
# 方法执行后
def tearDown(self):
pass
案例分析
断言
让程序替代人为判断测试程序执行结果是否符合预期的过程,可以提高测试效率实现自动化测试。
使用断言,要通过self.方法使用,断言的结果有两种:
1、True,用例通过
2、False,用例不通过,抛出异常
常用assertEqual和assertIn两种基本方法。
assertEqual
self.assertEqual(预期结果,实际结果)
判断预期结果与实际结果是否相等
1、两者相等则为True
2、两者不等则为False
assertIn
self.assertIn(预期结果,实际结果)
判断预期结果是否包含在实际结果之中
1、包含则为True
2、不包含则为False
class TestLogin(unittest.TestCase):
def testcase1(self):
if login.login('admin','123456')=='登录成功':
print('pass')
else:
print('fail')
# 以上if语句可改写
self.assertEqual('登录成功',login.login('admin','123456'))
self.assertIn('成功',login.login('admin','123456'))
参数化
测试方法中使用变量来代替具体的测试数据,用传参的方法将测试数据传递给方法的变量,提高用例使用效率。测试数据一般在json文件中,所以需要读取json文件以获取需要的数据。
安装插件
unittest本身是不支持参数化,因此需要安装插件parameterized来实现。
pip install parameterized
import unittest
from parameterizezd import parameterizezd
import login
# 数据顺序需与测试方法的参数顺序一致
data=[
('admin','123456','登录成功'),
('root','123456','登录成功'),
('admin','123123','登录成功'),
('root','123123','登录成功'),
]
class TestLogin(unittest.TestCase):
# 获取数据
@parameterizezd.expand(data)
def testcase1(self,username,password,expect):
self.assertEqual(expect,login.login(username,password))
跳过
对于一些未完成的或者不满足测试条件的测试函数和测试类,可以跳过执行。代码书写在测试用例文件中的测试方法前
@unittest.skip('跳过原因')
@unittest.skipif(判断条件,'跳过原因')
测试报告
自带测试报告
Pycharm运行TestCase会有自带的测试报告
第三方测试报告
HTMLTestRunner
是用于执行测试用例并生成自动化测试报告的工具。
# 1、获取第三方测试运行类模块,将其放在代码目录中
# 2、导包
import unittest
from HTMLTestRunner import HTMLTestRunner
# 3、实例化套件对象并加载用例
suite=unittest.defaultTestLoader.discover('用例所在路径','用例文件名')
# 4、实例化第三方运行对象并运行套件对象
# HTMLTestRunner(stream,verbosity,title,description)
# stream=sys.stdout,必填,测试报告的文件对象,使用wb方式打开,以二进制形式写入
# verbosity=1,可选,报告的详细程序,默认1简略,2详细
# title=None,可选,测试报告的标题
# description=None,可选,描述信息,Python/Pycharm的版本
file='report.html'
with open(file,'wb')as f:
runner=HTMLTestRunner(f,2,'测试报告','Python3.6')
runner.run(suite)
不同IDE运行
Pycharm运行
(尚未实践)
运行结果中 .表示用例通过,F表示用例不通过,E表示用例代码有问题
VSCode运行
需要配置unittest,ctrl+shift+P,搜索Python:Configure tests —— unittest —— 包含测试用例的路径 —— 命名方式。
点击左侧绿色图标运行单个方法,或者光标定位到类,右键运行所有方法