10天玩转Python第10天:python unittest框架 全面详解与代码示例

目录

  • 1.unittest 组成
  • 2.断言
  • 3.参数化
  • 4.测试报告

今日内容

  • unittest 框架的组成
    • TestLoader
    • Fixture
  • 断言
  • 跳过(某些用例由于某些原因不想执行)
  • 参数化
  • 测试报告
    ​​​​在这里插入图片描述

1.unittest 组成

TestLoader (测试加载)

TestLoader (测试加载), 作用和 TestSuite 的作用是一样的, 对 TestSuite 功能的补充,
用来组装测试用例的
比如: 如果 TestCase 的代码文件有很多, (10 20, 30 )
- 使用步骤
1. 导包
2. 实例化测试加载对象并添加用例 ---> 得到的是 suite 对象
3. 实例化 运行对象
4. 运行对象执行套件对象

代码实现

"""TestLoader 的使用"""
# 1, 导包
import unittest
# 2, 实例化加载对象并添加用例
# unittest.TestLoader().discover('用例所在的路径', '用例的代码文件名')
# 用例所在的路径,建议使用相对路径, 用例的代码文件名可以使用 *(任意多个任意字符) 通配符
# suite = unittest.TestLoader().discover('./case', 'hm*.py')
# suite = unittest.TestLoader().discover('./case', '*test*.py')
# suite = unittest.TestLoader().discover('./case', '*test*')
suite = unittest.TestLoader().discover('./case', '*case1.py')
# 3, 实例化运行对象
# runner = unittest.TextTestRunner()
# # 4, 执行
# runner.run(suite)
# 可以将 3 4 步 变为一步
unittest.TextTestRunner().run(suite)
# 1. 导包
# 2. 使用默认的加载对象并加载用例
# 3. 实例化运行对象并运行
"""TestLoader 的使用"""
# 1, 导包
import unittest
# 2, 使用默认的加载对象并加载用例
suite = unittest.defaultTestLoader.discover('case', 'hm_*.py')
# 可以将 3 4 步 变为一步
unittest.TextTestRunner().run(suite)

Fixture(测试夹具)

Fixture(测试夹具) 是一种代码结构
在某些特定的情况下 会自动执行

方法级别[掌握]

在这里插入代码片

在每个测试方法(用例代码) 执行前后都会自动调用的结构

# 方法执行之前
def setUp(self):
每个测试方法执行之前都会执行
pass
# 方法执行之后
def tearDown(self):
每个测试方法执行之后都会执行
pass

类级别[掌握]

在每个测试类中所有方法执行前后 都会自动调用的结构(在整个类中 执行之前执行之后个一次)

# 类级别的Fixture 方法, 是一个 类方法
# 类中所有方法之前
@classmethod
def setUpClass(cls):
pass
# 类中所有方法之后
@classmethod
def tearDownClass(cls):
pass

模块级别[了解]
模块: 代码文件
在每个代码文件执行前后执行的代码结构

# 模块级别的需要写在类的外边直接定义函数即可
# 代码文件之前
def setUpModule():
pass
# 代码文件之后
def tearDownModule():
pass

方法级别和类级别的 前后的方法,不需要同时出现,根据用例代码的需要自行的选择使用

案例

1. 打开浏览器(整个测试过程中就打开一次浏览器) 类级别
2. 输入网址(每个测试方法都需要一次) 方法级别
3. 输入用户名密码验证码点击登录(不同的测试数据) 测试方法
4. 关闭当前页面(每个测试方法都需要一次) 方法级别
5. 关闭浏览器(整个测试过程中就关闭一次浏览器) 类级别
------
1. 打开浏览器(整个测试过程中就打开一次浏览器) 类级别
2. 输入网址(每个测试方法都需要一次) 方法级别
3. 输入用户名密码验证码点击登录(不同的测试数据) 测试方法
4. 关闭当前页面(每个测试方法都需要一次) 方法级别
2. 输入网址(每个测试方法都需要一次) 方法级别
3. 输入用户名密码验证码点击登录(不同的测试数据) 测试方法
4. 关闭当前页面(每个测试方法都需要一次) 方法级别
2. 输入网址(每个测试方法都需要一次) 方法级别
3. 输入用户名密码验证码点击登录(不同的测试数据) 测试方法
4. 关闭当前页面(每个测试方法都需要一次) 方法级别
5. 关闭浏览器(整个测试过程中就关闭一次浏览器) 类级别
import unittest
class TestLogin(unittest.TestCase):
def setUp(self):
"""每个测试方法执行之前都会先调用的方法"""
print('输入网址......')
def tearDown(self) -> None:
"""每个测试方法执行之后都会调用的方法"""
print('关闭当前页面......')
@classmethod
def setUpClass(cls) -> None:
print('------1. 打开浏览器')
@classmethod
def tearDownClass(cls) -> None:
print('------5. 关闭浏览器')
def test_1(self):
print('输入正确用户名密码验证码,点击登录 1')
def test_2(self):
print('输入错误用户名密码验证码,点击登录 2')

2.断言

让程序代替人工自动的判断预期结果和实际结果是否相符.
断言的结果有两种:
> True, 用例通过
> False, 代码抛出异常, 用例不通过
在 unittest 中使用断言, 都需要通过 self.断言方法 来试验

assertEqual

self.assertEqual(预期结果, 实际结果) # 判断预期结果和实际结果是否相等
1. 如果相等, 用例通过
2. 如果不相等,用例不通过, 抛出异常

assertIn

self.assertIn(预期结果, 实际结果) # 判断预期结果是否包含在实际结果中
1. 包含 ,用例通过
2. 不包含, 用例不通过, 抛出异常
assertIn('admin', 'admin') # 包含
assertIn('admin', 'adminnnnnnnn') # 包含
assertIn('admin', 'aaaaaadmin') # 包含
assertIn('admin', 'aaaaaadminnnnnnn') # 包含
assertIn('admin', 'addddddmin') # 不是包含
import unittest
from tools import login
class TestLogin(unittest.TestCase):
def test_username_password_ok(self):
"""正确的用户名和密码: admin, 123456, 登录成功"""
self.assertEqual('登录成功', login('admin', '123456'))
def test_username_error(self):
"""错误的用户名: root, 123456, 登录失败"""
self.assertEqual('登录失败', login('root', '123456'))
def test_password_error(self):
"""错误的密码: admin, 123123, 登录失败"""
self.assertEqual('登录失败', login('admin', '123123'))
def test_username_password_error(self):
"""错误的用户名和错误的密码: aaa, 123123, 登录失败"""
# self.assertEqual('登录失败', login('aaa', '123123'))
self.assertIn('失败', login('aaa', '123123'))

3.参数化

参数化 在测试方法中, 使用 变量 来代替具体的测试数据, 然后使用传参的方法将测试数据传递给方法的变量
好处: 相似的代码不需要多次书写.
工作中场景:
1. 测试数据一般放在 json 文件中
2. 使用代码读取 json 文件,提取我们想要的数据 ---> [(), ()] or [[], []]

安装插件

unittest 框架本身是不支持 参数化, 想要使用参数化,需要安装插件来完成
- 联网安装(在 cmd 窗口安装 或者 )
pip install parameterized
------
pip 是 Python 中包(插件) 的管理工具, 使用这个工具下载安装插件

验证

pip list # 查看到 parameterized
新建一个 python 代码文件, 导包验证
from pa... import pa...

在这里插入图片描述
参数化代码

1. 导包 unittest/ pa
2. 定义测试类
3. 书写测试方法(用到的测试数据使用变量代替)
4. 组织测试数据并传参

在这里插入图片描述
参数化 2

[
{
"desc": "正确的用户名和密码",
"username": "admin",
"password": "123456",
"expect": "登录成功"
},
{
"desc": "错误的的用户名",
"username": "root",
"password": "123456",
"expect": "登录失败"
},
{
"desc": "错误的的密码",
"username": "admin",
"password": "123123",
"expect": "登录失败"
}
]
import json
import unittest
from parameterized import parameterized
from tools import login
# 组织测试数据 [(), (), ()] or [[], [], []]
def build_data():
with open('data.json', encoding='utf-8') as f:
result = json.load(f) # [{}, {}, {}]
data = []
for i in result: # i {}
data.append((i.get('username'), i.get('password'), i.get('expect')))
return data# 2. 定义测试类
class TestLogin(unittest.TestCase):
# 3. 书写测试方法(用到的测试数据使用变量代替)
@parameterized.expand(build_data())
def test_login(self, username, password, expect):
self.assertEqual(expect, login(username, password))
# 4. 组织测试数据并传参(装饰器 @)

跳过
对于一些未完成的或者不满足测试条件的测试函数和测试类, 不想执行,可以使用跳过使用方法, 装饰器完成
代码书写在 TestCase 文件

# 直接将测试函数标记成跳过
@unittest.skip('跳过额原因')
# 根据条件判断测试函数是否跳过 , 判断条件成立, 跳过
@unittest.skipIf(判断条件, '跳过原因')
import unittest
# version = 30
version = 29
class TestDemo(unittest.TestCase):
@unittest.skip('没有什么原因,就是不想执行')
def test_1(self):
print('测试方法 1')
@unittest.skipIf(version >= 30, '版本大于等于 30, 不用测试')
def test_2(self):
print('测试方法 2')
def test_3(self):
print('测试方法 3')

4.测试报告

自带的测试报告
只有单独运行 TestCase 的代码,才会生成测试报告
生成第三方的测试报告

  1. 获取第三方的 测试运行类模块 , 将其放在代码的目录中
  2. 导包 unittest
  3. 使用 套件对象, 加载对象 去添加用例方法
  4. 实例化 第三方的运行对象 并运行 套件对象
# 1. 获取第三方的 测试运行类模块 , 将其放在代码的目录中
# 2. 导包 unittest
import unittest
from HTMLTestRunner import HTMLTestRunner
# 3. 使用 套件对象, 加载对象 去添加用例方法
suite = unittest.defaultTestLoader.discover('.', 'hm_05_pa1.py')
# 4. 实例化 第三方的运行对象 并运行 套件对象
# HTMLTestRunner()
# stream=sys.stdout, 必填,测试报告的文件对象(open ), 注意点,要使用 wb 打开
# verbosity=1, 可选, 报告的详细程度,默认 1 简略, 2 详细
# title=None, 可选, 测试报告的标题
# description=None 可选, 描述信息, Python 的版本, pycharm 版本
# file = 'report.html' # 报告的后缀是.html
file = 'report1.html' # 报告的后缀是.html
with open(file, 'wb') as f:
# runner = HTMLTestRunner(f) # 运行对象
runner = HTMLTestRunner(f, 2, '测试报告', 'python 3.6.8 ') # 运行对象
# 运行对象执行套件, 要写在 with 的缩进中
runner.run(suite)
  1. 组织用例文件(TestCase 里边), 书写参数化, 书写断言, 书写 Fixture, 书写 跳过, 如果单个测试测试文
    件, 直接运行, 得到测试报告, 如果有多个测试文件, 需要组装运行生成测试报告
  2. 使用 套件对象组装, 或者使用 加载对象组装
  3. 运行对象 运行
    3.1 运行对象 = 第三方的运行类(文件对象(打开文件需要使用 wb 方式))
    3.2 运行对象.run(套件对象)
import unittest
from HTMLTestRunnerCN import HTMLTestReportCN
# 组装用例方法
suite = unittest.defaultTestLoader.discover('.', '*pa1.py')
# 实例化运行对象
with open('report_cn.html', 'wb') as f:
runner = HTMLTestReportCN(f)
runner.run(suite)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/230545.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

亚信安慧AntDB数据库助力智慧高速建设

随着新型智慧交通业务的迅速发展,各地高速公路在管控、收费和监测方面的数据管理变得至关重要。智慧公路信息化建设已成为高速公路建设的核心。AntDB数据库在某省级客户中发挥关键作用,帮助构建协同共享、高效的统一智慧管理平台,为高速公路的…

内网BUG管理系统本地部署并结合内网穿透实现异地远程访问

文章目录 前言1. 本地安装配置BUG管理系统2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射本地服务3. 测试公网远程访问4. 配置固定二级子域名4.1 保留一个二级子域名5.1 配置二级子域名6. 使用固定二级子域名远程 前言 BUG管理软件,作为软件测试工程师的必备工具之一。在…

app上架-.您的应用在首次打开或运行中,未见使用权限对应的相关功能或服务时,提前向用户弹窗申请开启【已安装应用列表】权限,不符合华为应用市场审核标准。

上架提示 您的应用在首次打开或运行中,未见使用权限对应的相关功能或服务时,提前向用户弹窗申请开启【已安装应用列表】权限,不符合华为应用市场审核标准。 测试步骤:首次打开APP,在首页页面,非服务所必须…

实验4.1 静态路由的配置

实验4.1 静态路由的配置 一、任务描述二、任务分析三、具体要求四、实验拓扑五、任务实施1.设置交换机和路由器的基本配置。2.使用display ip interface brief命令查看接口配置信息。3.配置静态路由,实现全网互通。 六、任务验收七、任务小结 一、任务描述 某公司刚…

Linux常用网络指令

网络参数设定使用的指令 手动/自动设定与启动/关闭 IP 参数&#xff1a;ifconfig, ifup, ifdown ifconfig ifconfig常用于修改网络配置以及查看网络参数的指令 [rootwww ~]# ifconfig {interface} {up|down} < 观察与启动接口 [rootwww ~]# ifconfig interface {options…

钡铼无线R10A工业级路由器在工业机器人领域的创新应用

随着工业机器人的普及&#xff0c;对于高可靠性和高稳定性的网络接入设备的需求也越来越大。传统的有线网络虽然稳定&#xff0c;但在现场布置和维护上面临很多困难&#xff0c;而无线网络虽然方便&#xff0c;但受到信号干扰和传输距离限制等问题的影响。如何解决这些问题&…

解决 Hbuilder打包 Apk pad 无法横屏 以及 H5 直接打包 成Apk

解决 Hbuilder打包 Apk pad 无法横屏 前言云打包配置 前言 利用VUE 写了一套H5 想着 做一个APP壳 然后把 H5 直接嵌进去 客户要求 在pad 端 能够操作 然后页面风格 也需要pad 横屏展示 云打包 配置 下面是manifest.json 配置文件 {"platforms": ["iPad"…

优优嗨聚集团美团代运对外卖市场的影响与作用

随着互联网的普及和消费者对便捷生活需求的增加&#xff0c;外卖市场逐渐成为人们日常生活中不可或缺的一部分。在这个竞争激烈的市场中&#xff0c;美团代运作为外卖配送领域的佼佼者&#xff0c;对外卖市场产生了深远的影响。本文将探讨美团代运对外卖市场的作用&#xff0c;…

Spring Cloud Alibaba核心技术宝典,分布式系统中间件实战案例(百度云下载)

前言 《Spring Cloud Alibaba学习笔记》其实是阿里的微服务解决方案&#xff0c;是阿里巴巴结合自身微服务实践,开源的微服务全家桶&#xff0c;在Spring Cloud项目中孵化成为Spring Cloud的子项目。第一代的Spring Cloud标准中很多组件已经停更,如&#xff1a;Eureak,zuul等。…

HBase shell 基础实操

目录 1 查看 HBase 状态 2 查看帮助命令 3 查看版本号 4 命名空间操作 5 创建表 6 列出所有的表 7 获取表描述 8 删除列族 9 其他 DDL 操作 1 查看 HBase 状态 进入 HBase 客户端命令行&#xff1a; (base) [roothadoop01 ~]# hbase shell hbase:001:0> statu…

工业物联网为什么更倾向使用蓝牙技术进行对接?

工业物联网更倾向使用蓝牙技术进行对接的原因主要有以下几点&#xff1a; 1、抗干扰能力强&#xff1a;蓝牙技术使用2.4GHz ISM频段&#xff0c;尽管这个频段繁忙&#xff0c;但蓝牙仍然具有确保消息成功到达目的地的巧妙方法。自适应跳频有助于确保数据成功通过噪声&#xff0…

比 ESLint 快50倍的OxLint 发布了!

告诉大家一个好消息&#xff0c;OxLint 现在正式发布了&#xff01;OxLint 是一个 JavaScript 代码检查工具&#xff0c;与 ESLint 类似&#xff0c;但它不需要复杂的配置&#xff0c;能够帮助我们捕捉错误或无用代码。与 ESLint 相比&#xff0c;OxLint 使用 Rust 编写&#x…

计算机图形学头歌合集(题集附解)

目录 CG1-v1.0-点和直线的绘制 第1关&#xff1a;OpenGL点的绘制 第2关&#xff1a;OpenGL简单图形绘制 第3关&#xff1a;OpenGL直线绘制 第4关&#xff1a;0<1直线绘制-dda算法<> 第5关&#xff1a;0<1直线绘制-中点算法<> 第6关&#xff1a;一般直线绘…

数据库增删改查Native SQL

DBCO&#xff1a;检查数据库是否连接 代码&#xff1a; 查询&#xff1a; DATA: gv_dbs TYPE char30 VALUE XXXXXXXX. "数据库连接名称 DATA:gt_ztclaim_2 TYPE TABLE OF ztclaim_2. DATA:gs_ztclaim_2 TYPE ztclaim_2.TRY.EXEC SQL.CONNECT TO :GV_DBSENDEXEC.EXEC SQ…

如何用UI自动化测试实现元素定位

随着IT行业的发展&#xff0c;产品愈渐复杂&#xff0c;web端业务及流程更加繁琐&#xff0c;目前UI测试仅是针对单一页面&#xff0c;操作量大。为了满足多页面功能及流程的需求及节省工时&#xff0c;设计了这款UI 自动化测试程序。旨在提供接口&#xff0c;集成到蜗牛自动化…

nacos配置导出

1.查看nacos数据库 mysql -u root -p use nacos show tables; 其中config_info就是存放nacos配置的表&#xff0c;导出该表中的数据就是导出nacos中的配置项 mysqldump -u root -p --single-transaction nacos config_info>config_info.sql 导出后在需要的nacos集群的…

我记不住的那些vim操作2

背景&#xff1a;最近在重新学习vi/vim&#xff0c;发现这个编辑器的用法真是太灵活了&#xff0c;所能掌控的也太多了&#xff0c;这次学习了一些之前没有学习过的内容&#xff0c;之前都是移动鼠标、编辑、复制、粘贴、保存等等(点我查看)&#xff0c;本次将介绍 标签、区域、…

【Python基础】生成器

文章目录 [toc]什么是生成器生成器示例生成器工作流程生成器表达式send()方法和close方法send()方法close()方法 什么是生成器 在Python中&#xff0c;使用生成器可以很方便地支持迭代器协议生成器通过生成器函数产生&#xff0c;通过def定义&#xff0c;但不是通过return返回…

亚马逊云科技re:Invent推出生成式AI技术堆栈及关键服务和工具

亚马逊云科技于29日推出“生成式AI技术堆栈”后&#xff0c;又在30日的re:Invent 2023大会上宣布了一系列支持这一全新堆栈的关键服务和工具。 亚马逊云科技数据和人工智能副总裁Swami Sivasubramanian在主题演讲中&#xff0c;将生成式人工智能与“超新星爆炸”进行了比较&am…

Python计算圆的面积,几何学技法大解析!

更多Python学习内容&#xff1a;ipengtao.com 大家好&#xff0c;我是彭涛&#xff0c;今天为大家分享 Python计算圆的面积&#xff0c;几何学技法大解析&#xff0c;全文3800字&#xff0c;阅读大约15分钟。 在本文中&#xff0c;将深入探讨如何使用 Python 计算圆的面积&…