Python基础学习(六)unittest 框架
1.介绍
是 Python自带的单元测试框架
- 自带的, 可以直接使用, 不需要单外安装
- 测试人员,用来做自动化测试, 作为自动化测试的执行框架,即管理和执行用例的
核心要素:
- TestCase 测试用例, 这个测试用例是 unittest 的组成部分,作用是用来书写真正的用例代码(脚本)
- Testsuite 测试套件, 作用是用来组装(打包)TestCase(测试⽤例) 的,即 可以将多个用例脚本文件 组装到⼀起
- TestRunner 测试执行(测试运行), 作用是用例执行TestSuite(测试套件)的
- TestLoader 测试加载, 是对 TestSuite(测试套件) 功能的补充, 作用是用来组装(打包) TestCase(测试⽤例) 的
- Fixture 测试夹具, 是⼀种代码结构, 书写前置方法(执行用例之前的方法)代码和后置方法(执行用例之后的方法) 代码 ,即用例执行顺序 前置 ---> ⽤例 ---> 后置
2.TestCase 测试用例
- 步骤
1. 导包 unittest
2. 定义测试类, 需要继承 unittest.TestCase 类, 习惯性类名以 Test 开头
3. 书写测试⽅法, 必须以 test 开头
4. 执⾏
- 注意事项
1. 代码⽂件名字 要满⾜标识符的规则
2. 代码⽂件名 不要使⽤中⽂
- 代码
"""
学习 TestCase(测试⽤例) 的使⽤
"""
# 1. 导包 unittest
import unittest
# 2. 定义测试类, 只要继承 unittest.TestCase 类, 就是测试类
class TestDemo(unittest.TestCase):
# 3. 书写测试⽅法, ⽅法中的代码就是真正⽤例代码,⽅法名必须以 test 开头
def test_method1(self):
print('测试⽅法⼀')
def test_method2(self):
print('测试⽅法⼆')
# 4. 执⾏
# 4.1 在类名或者⽅法名后边右键运⾏
# 4.1.1 在类名后边, 执⾏类中的所有的测试⽅法
# 4.1.2 在⽅法名后边, 只执⾏当前的测试⽅法
# 4.1 在主程序使⽤使⽤ unittest.main() 来执⾏,
if __name__ == '__main__':
unittest.main()
2.1可能出现的错误
文件名中包含中文
右键运行没有 unittest for ....
- 解决方案一
新建⼀个代码⽂件, 将之前的代码复制过来、
- 解决方案二
# 4.1 在主程序使⽤使⽤ unittest.main() 来执⾏,
if __name__ == '__main__':
unittest.main()
3.TestSuite 和 TestRunner
3.1TestSuite(测试套件)
将多条用例脚本集合在⼀起,就是套件, 即用来组装用例的
1. 导包 unittest
2. 实例化套件对象 unittest.TestSuite()
3. 添加用例方法
3.2TestRunner(测试执行)
用来执行套件对象
1. 导包 unittest
2. 实例化执行对象 unittest.TextTestRunner()
3. 执行对象执行 套件对象 执行对象.run(套件对象)
3.3整体步骤
1. 导包 unittest
2. 实例化套件对象 unittest.TestSuite()
3. 添加用例方法
3.1 套件对象.addTest(测试类名('测试方法名'))
4. 实例化 执行对象 unittest.TextTestRunner()
5. 执行对象执行套件对象 执行对象.run(套件对象)
3.4TestLoader 测试加载
作用和TestSuite作用⼀样,组装用例代码, 同样也需要使用TextTestRunner()去执行10 个用例脚本 makeSuite()
1. 导包 unittest
2. 实例化加载对象并加载用例 ---> 得到的是 套件对象
3. 实例化执行对象并执行
import unittest
# 实例化加载对象并加载⽤例,得到套件对象
# suite = unittest.TestLoader().discover('⽤例所在的⽬录', '⽤例代码⽂件名*.py')
suite = unittest.TestLoader().discover('.','pp_02*.py')
# 实例化执⾏对象并执⾏
# runner = unittest.TextTestRunner()
# runner.run(suite)
unittest.TextTestRunner().run(suite)
4.Fixture
代码结构, 在用例执行前后会自动执行的代码结构
tpshop 登录
1. 打开浏览器 (⼀次)
2. 打开⽹⻚,点击登录 (每次)
3. 输⼊⽤户名密码验证码1,点击登录 (每次, 测试⽅法)
4. 关闭⻚⾯ (每次)
2. 打开⽹⻚,点击登录 (每次)
3. 输⼊⽤户名密码验证码2,点击登录 (每次, 测试⽅法)
4. 关闭⻚⾯ (每次)
2. 打开⽹⻚,点击登录 (每次)
3. 输⼊⽤户名密码验证码3,点击登录 (每次, 测试⽅法)
4. 关闭⻚⾯ (每次)
5. 关闭浏览器 (⼀次)
4.1方法级别 Fixture
在每个用例执行前后都会自动调用, 方法名是固定的
ef setUp(self): # 前置
# 每个⽤例执⾏之前都会⾃动调⽤
pass
def tearDown(self): # 后置
# 每个⽤例执⾏之后 都会⾃动调⽤
pass
# ⽅法前置 ⽤例 ⽅法后置
# ⽅法前置 ⽤例 ⽅法后置
4.2类级别 Fixture
在类中所有的测试方法执行前后会自动执行的代码, 只执行⼀次
# 类级别的 Fixture 需要写作类⽅法
@classmethod
def setUpClass(cls): # 类前置
pass
@classmethod
def tearDownClass(cls): # 后置
pass
# 类前置 ⽅法前置 ⽤例 ⽅法后置 ⽅法前置 ⽤例 ⽅法后置
类后置
5.断言
使用代码自动的判断预期结果和实际结果是否相符
assertEqual(预期结果,实际结果)
- 判断预期结果和实际结果是否相等,如果相等, 用例通过,如果不相等,抛出异常, 用例不通过
assertIn(预期结果,实际结果)
- 判断预期结果是否包含在 实际结果中, 如果存在,用例通过, 如果不存在,抛出异常,用例不通过
import unittest
class TestAssert(unittest.TestCase):
def test_equal_1(self):
self.assertEqual(10, 10) # 用例通过
def test_assert_2(self):
self.assertEqual(10, 11) # 用例不通过
def test_in(self):
# self.assertIn('admin', '欢迎 admin 登录') # 包含 通过
# self.assertIn('admin', '欢迎 adminnnnnnnn 登录') # 包含 通过
# self.assertIn('admin', '欢迎 aaaaaadminnnnnnnn 登录') # 包含 通过
# self.assertIn('admin', '欢迎 adddddmin 登录') # 不包含 不通过
self.assertIn('admin', 'admin') # 包含 通过
import unittest
from p_02_assert import TestAssert
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestAssert))
unittest.TextTestRunner().run(suite)
6.参数化
- 通过参数的方式来传递数据,从而实现数据和脚本分离。并且可以实现用例的重复执行。(在书写用例方法的时候,测试数据使用变量代替,在执行的时候进行据说传递)
- unittest 测试框架,本身不支持参数化,但是可以通过安装unittest扩展插 件 parameterized 来实现。
6.1环境准备
因为参数化的插件 不是 unittest 自带的,所以想要使用 需要进行安装Python 中 包(插件,模块) 的安装,使用 pip 工具
pip install parameterized
pip install -i https://pypi.douban.com/simple/ parameterized
# 在终端(cmd)中执行
6.2使用
1. 导包 from para... import para...
2. 修改测试方法,将测试方法中的测试数据使用 变量表示
3. 组织测试数据,格式 [(), (), ()], 一个元组就是一组测试数据
4. 参数化,在测试方法上方使用装饰器 @parameterized.expand(测试数据)
5. 运行(直接 TestCase 或者 使用 suite 运行)
import unittest
from tools import add
from parameterized import parameterized
data = [(1, 1, 2), (1, 2, 3), (2, 3, 5), (4, 5, 9)]
class TestAdd(unittest.TestCase):
@parameterized.expand(data)
def test_add(self, a, b, expect):
print(f'a:{a}, b:{b}, expect:{expect}')
self.assertEqual(expect, add(a, b))
if __name__ == '__main__':
unittest.main()
7.测试报告
使用第三方的报告模版,生成报告 HTMLTestReport, 本质是 TestRunner
- 安装
pip install -i https://pypi.douban.com/simple/ HTMLTestReport
- 使用
1. 导包 unittest、HTMLTestReport
2. 组装用例(套件, loader )
3. 使用 HTMLTestReport 中的 runner 执行套件
4. 查看报告
import unittest
from htmltestreport import HTMLTestReport
from hm_04_pa1 import TestAdd
# 套件
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestAdd))
# 运行对象
# runner = HTMLTestReport(报告的文件路径后缀.html, 报告的标题, 其他的描述信息)
runner = HTMLTestReport('test_add_report.html', '加法用例测试报告', 'xxx')
runner.run(suite)
7.1使用绝对路径
将来的项目是分目录书写的, 使用相对路径,可能会出现找不到文件的情况,此时需要使用 绝对路径
方法:
1. 在项目的根目录,创建一个 Python 文件(app.py 或者 config.py)
2. 在这个文件中 获取项目的目录,在其他代码中使用 路径拼接完成绝对路径的书写
- 获取当前文件的绝对路径:abspath=os.path.abspath(_file_)
- 获取文件路径的目录名称:dirname=os.path.dirname(filepath)
import os
# __file__ 特殊的变量,表示当前代码文件名
# path1 = os.path.abspath(__file__)
# print(path1)
# path2 = os.path.dirname(path1)
# print(path2)
# BASE_DIR = os.path.dirname(os.path.abspath(__file__))
BASE_DIR = os.path.dirname(__file__)
if __name__ == '__main__':
print(BASE_DIR)
原文地址:https://blog.csdn.net/weixin_48672484/article/details/145266800
免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!