python-UnitTest框架笔记
UnitTest框架的基本使用方法
UnitTest框架介绍
框架:framework,为了解决一类事情的功能集合
UnitTest框架:是python自带的单元测试框架
自带的,可以直接使用,不需要格外安装
测试人员用来做自动化测试,作为自动化测试的执行框架,即管理和执行测试用例的
使用原因:
能够组织多个用例去执行
提供丰富的断言方法
能够生成测试报告
核心要素(组成):
-TestCase测试用例,这个测试用例是UnitTest的组成部分,作用是用来书写真正的用例代码(脚本)
-TestSuite测试套件,作用是用来组装TestCase的,即可以将多个用例脚本文件组装到一起
-TestRunner测试执行,作用是用来执行TestSuite的
-TestLoader测试加载,是对TestSuite功能的补充,作用是用来组装TestCase的
-Fixture测试夹具,是一种代码结构,书写前置方法代码和后置方法代码,即用例执行顺序:前置–>用例–>后置
TestCase测试用例
书写真正的用例代码(脚本)
步骤:
-1.导包unittest
-2.定义测试类
-3.书写测试方法
-4.执行
注意事项:
代码文件名字要满足标识符的规则
代码文件名不要使用中文
代码:
#导包
import unittest
#定义测试类,只要继承unittest.TestCase类,就是测试类
class TestDemo(unittest.TestCase):#书写测试方法,方法中的代码就是真正的用例代码,方法名必须以test开头def test_method1(self):print("测试方法一")def test_method2(self):print("测试方法二")
#执行
#在类名或者方法名后边右键运行
#在类名后边,执行类中的所有测试方法
#在方法名后边,只执行当前的测试方法#在主程序中使用unittest.main()来执行
if __name__ == '__main__':unittest.main()
TestCase常见错误
1.文件名包含中文-------执行可能报错
2.右键运行没有unittest for …
解决方法一:新建一个代码文件,将之前的代码复制过来
解决方法二:使用unittest.main()运行
解决方法三:
TestSuite和TestRunner的使用
TestSuite测试套件:将多条脚本集合在一起,就是套件,即用来组装用例的
1.导包unittest
2.实例化套件对象unittest.TestSuite()
3.添加用例方法,套件对象.addTest(测试类名(测试方法名))
TestRunner测试执行:用来执行套件对象
1.导包unittest
2.实例化执行对象unittest.TextTestRunner()
3.执行对象执行套件对象,执行对象.run(套件对象)
整体步骤:
1.导包unittest
2.实例化套件对象unittest.TestSuite()
3.添加用例方法,套件对象.addTest(测试类名(测试方法名))
4.实例化执行对象unittest.TextTestRunner()
5.执行对象执行套件对象,执行对象.run(套件对象)
代码案例
套件可以用来组装用例,创建多个代码用例
#导包
import unittest
#定义测试类,只要继承unittest.TestCase类,就是测试类
class TestDemo1(unittest.TestCase):#书写测试方法,方法中的代码就是真正的用例代码,方法名必须以test开头def test_method1(self):print("测试方法1-1")def test_method2(self):print("测试方法1-2")
#导包
import unittest
#定义测试类,只要继承unittest.TestCase类,就是测试类
class TestDemo2(unittest.TestCase):#书写测试方法,方法中的代码就是真正的用例代码,方法名必须以test开头def test_method1(self):print("测试方法2-1")def test_method2(self):print("测试方法2-2")
#1.导包unittest
import unittestfrom unittest1.TestCase.yongli1 import TestDemo2
from unittest1.TestCase.yongli2 import TestDemo1#2.实例化套件对象unittest.TestSuite()
suite=unittest.TestSuite()
#3.添加用例方法,套件对象.addTest(测试类名(测试方法名))
suite.addTest(TestDemo1('test_method1'))
suite.addTest(TestDemo1('test_method2'))
suite.addTest(TestDemo2('test_method1'))
suite.addTest(TestDemo2('test_method2'))
#4.实例化执行对象unittest.TextTestRunner()
runner=unittest.TextTestRunner()
#5.执行对象执行套件对象,执行对象.run(套件对象)
runner.run(suite)
添加整个测试类中的方法
方法一
套件对象.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(测试类名))
#把指定测试类中的测试用例全部添加到测试套件中
方法二
套件对象.addTest(unittest.makeSuite(测试类名))
#1.导包unittest
import unittestfrom unittest1.TestCase.yongli1 import TestDemo2
from unittest1.TestCase.yongli2 import TestDemo1#2.实例化套件对象unittest.TestSuite()
suite=unittest.TestSuite()
#3.添加用例方法,套件对象.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(测试类名))
suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(TestDemo1))
suite.addTest(unittest.makeSuite(TestDemo2))
#4.实例化执行对象unittest.TextTestRunner()
runner=unittest.TextTestRunner()
#5.执行对象执行套件对象,执行对象.run(套件对象)
runner.run(suite)
查看测试结果

TestLoader测试加载:

作用和TestSuite作用一样,组装用例代码,同样也需要使用TextTestRunner()方法去执行
TestLoader加载用例更加方便
1.导包import unittest
2.实例化加载对象并加载用例---->得到的是套件对象
3.实例化执行对象并执行
#1.导包
import unittest
#2.实例化加载对象并加载用例---->得到的是套件对象
suite=unittest.TestLoader().discover('.','yongli*.py') #参数1:用例所在目录,参数2:用例代码文件名
#3.实例化执行对象并执行
runner=unittest.TextTestRunner()
runner.run(suite)
练习
练习1

用例代码
#导包
import unittest
#定义测试类,只要继承unittest.TestCase类,就是测试类
class TestDemo1(unittest.TestCase):#书写测试方法,方法中的代码就是真正的用例代码,方法名必须以test开头def test_method(self):print("测试方法1")
执行代码
import unittestsuite=unittest.TestLoader().discover('./case','test_*.py')
unittest.TextTestRunner().run(suite)

练习2

import unittest
from tools1 import add
class TestDemo(unittest.TestCase):def test_method1(self):if add(1,1) == 2:print("测试通过")else:print("测试失败")def test_method2(self):if add(2,1) == 3:print("测试通过")else:print("测试失败")def test_method3(self):if add(3,4) == 7:print("测试通过")else:print("测试失败")def test_method4(self):if add(4,5) == 9:print("测试通过")else:print("测试失败")
import unittestsuite=unittest.TestLoader().discover('.','test_*.py')unittest.TextTestRunner().run(suite)
fixture说明
代码结构,在用例执行前后会自动执行的代码结构
tpshop登录
1.打开浏览器(一次)
2.打开网页,点击登录(每次)
3.输入用户名,密码,验证码,点击登录(每次)
4.关闭页面(每次)
5.关闭浏览器(一次)
方法级别Fixture:
在每个用例执行前后都会自动调用,方法名是固定的
def setUp(self): #前置方法,每个用例执行前调用
pass
def tearDown(self): #后置方法,每个用例执行之后都会调用
pass
类级别Fixture:
在类中所有的测试方法执行前后,会自动执行的代码,类开始前执行和类执行结束时执行一次
类级别的Fixture需要写作类方法
@classmethod
def setUpClass(cls): #前置方法,类执行前调用
pass
@classmethod
def tearDownClass(cls): #后置方法,类执行之后都会调用
pass
模块级别Fixture:
模块就是代码文件,在代码文件执行前后执行一次
在类外部定义函数
def setUpModule(): #前置
pass
def tearDownpModule(): #前置
pass
Fixture实现

测试用例
import unittestclass TestDemo(unittest.TestCase):@classmethoddef setUpClass(cls):print("打开浏览器")@classmethoddef tearDownClass(cls):print("关闭浏览器")def setUp(self):print("打开网页,点击登录")def tearDown(self):print("关闭页面")def test_method1(self):print("输入用户名密码验证码1,点击登录")def test_method2(self):print("输入用户名密码验证码2,点击登录")def test_method3(self):print("输入用户名密码验证码1,点击登录")
测试运行
import unittestsuite=unittest.TestLoader().discover('.','test_*.py')unittest.TextTestRunner().run(suite)
断言的使用
断言
使用代码自动判断预期结果和实际结果是否相等

练习

import unittest
from tools1 import add
class TestDemo(unittest.TestCase):def test_method1(self):self.assertEqual(2,add(1,1))def test_method2(self):self.assertEqual(3,add(1, 2))def test_method3(self):self.assertEqual(7,add(3, 4))def test_method4(self):self.assertEqual(9,add(4, 5))
import unittest
suite=unittest.TestLoader().discover('.','test_*.py')
unittest.TextTestRunner().run(suite)
实现参数化
参数化环境安装
通过参数的方式来传递数据,从而实现数据和脚本分离,并且可以实现用例的重复执行。(在书写用例方法的时候,测试数据使用变量代替,在执行的时候进行数据传递)
-unittest测试框架,本身不支持参数化,但是可以通过安装unittest扩展插件parameterized来实现。
因为参数化的插件不是unittest自带的,所以想要使用,需要进行安装
安装:pip install -i http://pypi.douban.com/simple parameterized
参数化
1.导包 from parameterized import parameterized
2.修改测试方法,将测试方法中的测试数据使用变量表示
3.组织测试数据,格式[(),(),()],一个元组就是一组测试数据
4.参数化,在测试方法上方使用装饰器@parameterized.expand(测试数据)
5.运行(直接运行TestCase或者使用suite运行)
import unittest
from parameterized import parameterized
from tools1 import addclass TestDemo(unittest.TestCase):list = [(1, 1, 2), (1, 2, 3), (3, 4, 7), (2, 3, 5)]@parameterized.expand(list)def test_method1(self,a,b,expect):self.assertEqual(expect,add(a,b))
练习1

import json
def getDate():with open('../package1/one.json', 'r', encoding='utf-8') as f:list=json.load(f)list1=[]for i in list:list1.append(tuple(i.values()))return list1
import unittest
from parameterized import parameterized
from lianxi2.getDate import getDate
from tools1 import addclass TestDemo(unittest.TestCase):@parameterized.expand(getDate())def test_method1(self,a,b,expect):self.assertEqual(expect,add(a,b))
测试报告和跳过
测试报告
使用第三方的报告模板,生成报告HTMLTestReport,本质是TestRunner
安装
pip install -i http://pypi.doouban.com/simple/ HTMLTestReport
使用
1.导包unittest;HTMLTestReport
2.组装用例(套件,loader)
3.使用HTMLTestReport中的runner执行
4.查看报告
import unittest
from htmltestreport import HTMLTestReportif __name__ == '__main__':#套件suite = unittest.TestLoader().discover('.', 'test_*.py')#运行runner=HTMLTestReport(报告文件目录, 报告标题,其他描述信息)runner=HTMLTestReport('report.html', '测试报告','add')runner.run(suite)

使用绝对路径
将来的项目是分目录书写的,使用相对路径,可能会出现找不到文件的情况,此时需要使用绝对路径
方法:
1.在项目的根目录,创建一个python文件(app.py或者config.py)
2.在这个文件中获取项目的目录,在其他代码中使用路径拼接完成绝对路径的书写

import os
#获取项目绝对路径
path1=os.path.abspath(__file__) #__file__ 是特殊变量,表示当前代码文件名
base_addr=os.path.dirname(path1)
import os
import unittest
from htmltestreport import HTMLTestReport
from base_addr import base_addrif __name__ == '__main__':#套件suite = unittest.TestLoader().discover('.', 'test_*.py')#运行runner=HTMLTestReport(报告文件目录, 报告标题,其他描述信息)#runner=HTMLTestReport('report.html', '测试报告','add')#绝对路径filepath=os.path.join(base_addr,'lianxi2/report/report.html')runner=HTMLTestReport(filepath, '测试报告','add')runner.run(suite)
案例

tools.py
def login(username,password):if username=='admin' and password=='123456':return '登录成功'else:return '登录失败'
测试数据one.json
[{"desc": "正确的用户名和密码","username": "admin","password":"123456","excpet":"登录成功"
}, {"desc": "错误密码","username": "admin","password":"admin","excpet":"登录失败"
}, {"desc": "错误用户名","username": "admin1","password":"123456","excpet":"登录失败"
}]
获取测试数据getDate.py
import json
def getDate():with open('../package1/one.json', 'r', encoding='utf-8') as f:list=json.load(f)list1=[]for i in list:list1.append(tuple(i.values())[1:])return list1
测试用例
import unittest
from parameterized import parameterized
from lianxi2.getDate import getDate
from tools import loginclass TestDemo(unittest.TestCase):@parameterized.expand(getDate())def test_method1(self,a,b,expect):self.assertEqual(expect,login(a,b))
执行并生成测试报告
import os
import unittest
from htmltestreport import HTMLTestReport
from base_addr import base_addrif __name__ == '__main__':#套件suite = unittest.TestLoader().discover('.', 'test_*.py')#运行runner=HTMLTestReport(报告文件目录, 报告标题,其他描述信息)#绝对路径filepath=os.path.join(base_addr,'lianxi2/report/report.html')runner=HTMLTestReport(filepath, '测试报告','login')runner.run(suite)
报告

跳过
对于一些未完成的或者不满足测试条件的测试函数和测试类,可以执行跳过(简单来说,不想执行的代码的存测试方法,可以设置跳过)
直接将测试函数标记成跳过
@unittest.skip(“跳过原因”)
根据条件判断测试函数是否跳过
@unittest.skipIf(判断条件,reason=‘原因’) #判断条件为True,执行跳过
import unittest
from parameterized import parameterized
from lianxi2.getDate import getDate
from tools1 import loginversion=30
class TestDemo(unittest.TestCase):@parameterized.expand(getDate())def test_method1(self,a,b,expect):self.assertEqual(expect,login(a,b))@unittest.skip("跳过举例")def test_method2(self):print("测试方法二")@unittest.skipIf(version>30,"版本大于30跳过")def test_method3(self):print("测试方法三")@unittest.skipUnless(version<30,"版本小于30跳过")def test_method4(self):print("测试方法四")
相关文章:
python-UnitTest框架笔记
UnitTest框架的基本使用方法 UnitTest框架介绍 框架:framework,为了解决一类事情的功能集合 UnitTest框架:是python自带的单元测试框架 自带的,可以直接使用,不需要格外安装 测试人员用来做自动化测试,作…...
掌握API和控制点(从Java到JNI接口)_35 JNI开发与NDK 03
3、 如何载入 .so档案 VM的角色 由于Android的应用层级类别都是以Java撰写的,这些Java类别转译为Dex型式的Bytecode之后,必须仰赖Dalvik虚拟机器(VM: Virtual Machine)来执行之。 VM在Android平台里,扮演很重要的角色。此外,在执…...
计算机组成原理——存储系统(二)
🌱 "人生最深的裂痕,往往是光照进来的地方。 别怕脚下的荆棘,那是你与平庸划清界限的勋章;别惧眼前的迷雾,星辰永远藏在云层之上。真正的强者不是从未跌倒,而是把每一次踉跄都踏成攀登的阶梯。记住&am…...
CDDIS从2025年2月开始数据迁移
CDDIS 将从 2025 年 2 月开始将我们的网站从 cddis.nasa.gov 迁移到 earthdata.nasa.gov,并于 2025 年 6 月结束。 期间可能对GAMIT联网数据下载造成影响。...
VSCode设置内容字体大小
1、打开VSCode软件,点击左下角的“图标”,选择“Setting”。 在命令面板中的Font Size处选择适合自己的字体大小。 2、对比Font Size值为14与20下的字体大小。...
嵌入式学习---蜂鸣器篇
1. 蜂鸣器分类 蜂鸣器是一种电子发声器件,采用直流电压供电,能够发出声音。广泛应用于计算机、打印机、报警器、电子玩具等电子产品中作为发声部件。一般仅从外形不易分辨蜂鸣器的种类。但是有些蜂鸣器使用广泛,见得多了就很容易分辨。例如常…...
【优先算法】专题——前缀和
目录 一、【模版】前缀和 参考代码: 二、【模版】 二维前缀和 参考代码: 三、寻找数组的中心下标 参考代码: 四、除自身以外数组的乘积 参考代码: 五、和为K的子数组 参考代码: 六、和可被K整除的子数组 参…...
【Linux】使用管道实现一个简易版本的进程池
文章目录 使用管道实现一个简易版本的进程池流程图代码makefileTask.hppProcessPool.cc 程序流程: 使用管道实现一个简易版本的进程池 流程图 代码 makefile ProcessPool:ProcessPool.ccg -o $ $^ -g -stdc11 .PHONY:clean clean:rm -f ProcessPoolTask.hpp #pr…...
使用Express.js和SQLite3构建简单TODO应用的后端API
使用Express.js和SQLite3构建简单TODO应用的后端API 引言环境准备代码解析1. 导入必要的模块2. 创建Express应用实例3. 设置数据库连接4. 初始化数据库表5. 配置中间件6. 定义数据接口7. 定义路由7.1 获取所有TODO项7.2 创建TODO项7.3 更新TODO项7.4 删除TODO项 8. 启动服务器 …...
Vue3 表单:全面解析与最佳实践
Vue3 表单:全面解析与最佳实践 引言 随着前端技术的发展,Vue.js 已经成为最受欢迎的前端框架之一。Vue3 作为 Vue.js 的最新版本,带来了许多改进和新的特性。其中,表单处理是 Vue 应用中不可或缺的一部分。本文将全面解析 Vue3 …...
找不到msvcp140.dll解决方法
您可以尝试以下方案进行修复,看看是否可以解决这个问题: 一、重新注册 msvcp140.dll 运行库文件: “WinR”打开运行,键入:regsvr32 MSVCP140.dll,回车即可; 如果出现找不到该文件的提示&…...
【优先算法】专题——位运算
在讲解位运算之前我们来总结一下常见的位运算 一、常见的位运算 1.基础为运算 << &:有0就是0 >> |:有1就是1 ~ ^:相同为0,相异位1 /无进位相加 2.给一个数 n,确定它的二进制表示…...
【Cadence仿真技巧学习笔记】求解65nm库晶体管参数un, e0, Cox
在设计放大器的第一步就是确定好晶体管参数和直流工作点的选取。通过阅读文献,我了解到L波段低噪声放大器的mos器件最优宽度计算公式为 W o p t . p 3 2 1 ω L C o x R s Q s p W_{opt.p}\frac{3}{2}\frac{1}{\omega LC_{ox}R_{s}Q_{sp}} Wopt.p23ωLCoxRs…...
AI模型升级版0.03
以下是一个升级版的代码实现,结合了最新的技术趋势,例如强化微调(Reinforcement Fine-Tuning)和一些优化改进,以提升模型的性能和易用性。以下是升级后的代码: 步骤 1:安装必要的库 确保安装了…...
Docker入门篇(Docker基础概念与Linux安装教程)
目录 一、什么是Docker、有什么作用 二、Docker与虚拟机(对比) 三、Docker基础概念 四、CentOS安装Docker 一、从零认识Docker、有什么作用 1.项目部署可能的问题: 大型项目组件较多,运行环境也较为复杂,部署时会碰到一些问题࿱…...
开源智慧园区管理系统对比其他十种管理软件的优势与应用前景分析
内容概要 在当今数字化快速发展的时代,园区管理软件的选择显得尤为重要。而开源智慧园区管理系统凭借其独特的优势,逐渐成为用户的新宠。与传统管理软件相比,它不仅灵活性高,而且具有更强的可定制性,让各类园区&#…...
【C++】P5734 【深基6.例6】文字处理软件
博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 💯前言💯题目描述💯题目描述输入格式输出格式示例输入与输出输入:输出: 💯我的做法操作1:在文档末尾插入字符串操作2&…...
doris:删除操作概述
在 Apache Doris 中,删除操作(Delete)是一项关键功能,用于管理和清理数据,以满足用户在大规模数据分析场景中的灵活性需求。 Doris 提供了丰富多样的删除功能支持,包括:DELETE 语句、删除标记&…...
CSS核心
CSS的引入方式 内部样式表是在 html 页面内部写一个 style 标签,在标签内部编写 CSS 代码控制整个 HTML 页面的样式。<style> 标签理论上可以放在 HTML 文档的任何地方,但一般会放在文档的 <head> 标签中。 <style> div { color: r…...
013-51单片机红外遥控器模拟控制空调,自动制冷制热定时开关
主要功能是通过红外遥控器模拟控制空调,可以实现根据环境温度制冷和制热,能够通过遥控器设定温度,可以定时开关空调。 1.硬件介绍 硬件是我自己设计的一个通用的51单片机开发平台,可以根据需要自行焊接模块,这是用立创…...
CMake项目编译与开源项目目录结构
Cmake 使用简单方便,可以跨平台构建项目编译环境,尤其比直接写makefile简单,可以通过简单的Cmake生成负责的Makefile文件。 如果没有使用cmake进行编译,需要如下命令:(以muduo库echo服务器为例)…...
网站快速收录:如何优化网站音频内容?
本文转自:百万收录网 原文链接:https://www.baiwanshoulu.com/60.html 为了优化网站音频内容以实现快速收录,以下是一些关键的策略和步骤: 一、高质量音频内容创作 原创性: 确保音频内容是原创的,避免使…...
pytorch基于GloVe实现的词嵌入
PyTorch 实现 GloVe(Global Vectors for Word Representation) 的完整代码,使用 中文语料 进行训练,包括 共现矩阵构建、模型定义、训练和测试。 1. GloVe 介绍 基于词的共现信息(不像 Word2Vec 使用滑动窗口预测&…...
deepseek接入pycharm 进行AI编程
要将DeepSeek接入PyCharm进行AI编程,可以按照以下步骤操作: ### 1. 获取DeepSeek API访问权限 DeepSeek通常以API的形式对外提供服务,你需要在其官方网站注册账号,申请API访问权限。在申请通过后,会获得API密钥(API Key),这是后续调用API的关键凭证。 ### 2. 安装必要…...
OPENPPP2 —— VMUX_NET 多路复用原理剖析
在阅读本文之前,必先了解以下几个概念: 1、MUX(Multiplexer):合并多个信号到单一通道。 2、DEMUX(Demultiplexer):从单一通道分离出多个信号。 3、单一通道,可汇聚多个…...
语言月赛 202412【正在联系教练退赛】题解(AC)
》》》点我查看「视频」详解》》》 [语言月赛 202412] 正在联系教练退赛 题目背景 在本题中,我们称一个字符串 y y y 是一个字符串 x x x 的子串,当且仅当从 x x x 的开头和结尾删去若干个(可以为 0 0 0 个)字符后剩余的字…...
想学习JAVA编程,请问应该如何去学习?
学习Java编程是一个系统而深入的过程,以下是一个详细的学习路径和建议: 一、明确学习目标和规划 确定学习方向:Java编程的应用领域广泛,包括企业级应用、Web开发、Android开发等。你需要明确自己的学习目标,比如是想…...
使用 HTTP::Server::Simple 实现轻量级 HTTP 服务器
在Perl中,HTTP::Server::Simple 模块提供了一种轻量级的方式来实现HTTP服务器。该模块简单易用,适合快速开发和测试HTTP服务。本文将详细介绍如何使用 HTTP::Server::Simple 模块创建和配置一个轻量级HTTP服务器。 安装 HTTP::Server::Simple 首先&…...
深入探讨DICOM医学影像中的WADO服务及其具体实现
1. 引言 随着数字化医学影像技术的普及,如何高效、安全地存储、管理和共享医学影像数据成为医疗行业亟待解决的关键问题。DICOM(Digital Imaging and Communications in Medicine)作为国际公认的医学影像标准,在全球范围内广泛应…...
【数据结构】_链表经典算法OJ:复杂链表的复制
目录 1. 题目链接及描述 2. 解题思路 3. 程序 1. 题目链接及描述 题目链接:138. 随机链表的复制 - 力扣(LeetCode) 题目描述: 给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,…...
