Python Unittest ddt数据驱动
1、数据驱动介绍:
- @ddt.ddt(类装饰器,申明当前类使用ddt框架)
- @ddt.data(函数装饰器,用于给测试用例传递数据),支持传python所有数据类型:数字(int,long,float,compix),字符串,列表1ist,元组tuple,集合,编写阅读数据文件的函数、@data入口参数加*读取
- @ddt.unpack(函致装饰器,将传输的数据包解包),一般作用于元组tuple和列表list、字典(参数名字和个数需要与字典的键保持一致)(数组、字符串不需要)
- @ddt.file_data(函数装饰器,可直接读取yaml/json文件)
2、数据驱动和关键驱动的区别:
- Data-Driven Tests(DDT)即数据驱动测试,可以实现不同数据运行同一个测试用例。ddt本质其实就是装饰器,一组数据一个场景。
- 关键字驱动(核心:把业务逻相封装成关键字login,只需要调用login。)
3、混合驱动模式(关键字驱动+数据驱动)
4、在进行数据驱动测试实战:需要在测试类上使用@ddt.ddt装饰器,在测试用例上使用@ddt.data装饰器。
(1)单一参数:导包——写一个参数(列表、数字、字符串)-----设置@ddt.data装饰器写入参数名----方法中写入形参*data----调用参数内容
(2)多参数的数据驱动测试(一个测试参数中含多个元素):导包——设置@ddt装饰器——设置@unpack解包——写入参数——形参传递——调用
(3)txt文件传参
(4)json文件传参
(5)yaml文件传参
(6)xlsx文件传参
注意:Python中传递可变参数:*代表顺序阅读列表类型,**代表顺序阅读对象(字典)类型,点击阅读可变参数部分可了解相关机制
# 1、单一参数的数据驱动# 前置步骤:
# 使用语句import unittest导入测试框架
# 使用语句from ddt import ddt, data导入单一参数的数据驱动需要的包# 示例会执行三次test,参数分别为'666','777','888'
import ddt
import unittest
@ddt.ddt # 设置@ddt装饰器
class BasicTestCase(unittest.TestCase):@ddt.data('666', '777', '888') # 设置@data装饰器,并将传入参数写进括号def test(self, *data): # test入口设置形参print('数据驱动的number:', data)
# 程序会执行三次测试,入口参数分别为666、777、888# 2、多参数的数据驱动
# 在单一参数包的基础上,额外导入一个unpack的包,from ddt import ddt, data, unpack
# 步骤:导包——设置@ddt装饰器——设置@unpack解包——写入参数——形参传递——调用
import ddt
import unittestTestdata = [{"username": "admin", "password": "123456", "excepted": {'code': '200', 'msg': '登录成功'}},{"username": None, "password": "1234567", "excepted": {'code': '400', 'msg': '用户名或密码不能为空'}},{"username": "admin", "password": None, "excepted": {'code': '400', 'msg': '用户名或密码不能为空'}},{"username": "admin", "password": "123456789", "excepted": {'code': '404', 'msg': '用户名或密码错误'}},
]@ddt.ddt
class BasicTestCase(unittest.TestCase):#方式一:直接将列表放到data@ddt.data(['张三', '18'], ['李四', '19']) # 设置@data装饰器,并将同一组参数写进中括号[]@ddt.unpack # 设置@unpack装饰器顺序解包,缺少解包则相当于name = ['张三', '18']def test(self, name, age):print('姓名:', name, '年龄:', age)
# 程序会执行两次测试,入口参数分别为['张三', '18'],['李四', '19']#方式二:写一个列表后,使用*访问列表到data@ddt.data(*Testdata)@ddt.unpack # 设置@unpack装饰器顺序解包def test_DataDriver(self, *Data):#print('DDT数据驱动实战演示:', Data)res = login.login_check(Testdata['username'], Testdata['password'])self.assertEqual(res, Testdata['excepted'])#3、 txt文件接收参数
# 新建num文件,txt格式# (1)单一参数按行存储777,888,999# (2)多参数txt文件# dict文件内容(参数列表)(按行存储):# 张三,18# 李四,19
# 编辑阅读数据文件的函数
# 记住读取文件一定要设置编码方式,否则读取的汉字可能出现乱码!!!!!!
import ddt
import unittest
def read_num():lis = [] # 以列表形式存储数据,以便传入@data区域with open('num.txt', 'r', encoding='utf-8') as file: # 以只读'r',编码方式为'utf-8'的方式,打开文件'num',并命名为filefor line in file.readlines(): # 循环按行读取文件的每一行lis.append(line.strip('\n')) #单一参数,每读完一行将此行数据加入列表元素,记得元素要删除'/n'换行符!!!#lis.append(line.strip('\n').split(',')) # 多参驱动,删除换行符,根据,分割后,列表为['张三,18', '李四,19', '王五,20']return lis # 将列表返回,作为@data接收的内容
@ddt.ddt
class BasicTestCase(unittest.TestCase):@ddt.data(*read_num()) # 入口参数设定为read_num(),因为返回值是列表,所以加*表示逐个读取列表元素#txt表格有多少个值,设置多少个接收参数的形参def test(self, name,age):print('数据驱动的number:', name,age)# 4、JSON文件传参:数据分离
# 多参数——json文件
# 步骤和单一参数类似,仅需加入@unpack装饰器以及多参数传参入口
# dict文件内容(参数列表)(非规范json文件格式):
# 单一参数:["666","777","888"]
# 多个参数:[["张三", "18"], ["李四", "19"], ["王五", "20"]]
# 注意json文件格式字符串用双引号
import ddt
import unittest
import json
def read_dict_json():return json.load(open('dict.json', 'r', encoding='utf-8')) # 使用json包读取json文件,并作为返回值返回
@ddt.ddt
class BasicTestCase(unittest.TestCase):@ddt.data(*read_dict_json())@ddt.unpack # 使用@unpack装饰器解包def test(self, name, age): # 因为是非规范json格式,所以形参名无限制,下文会解释规范json格式print('姓名:', name, '年龄:', age)# 4、JSON文件传参:数据分离
# json文件三种形式:
# (1)单一参数:["666","777","888"]
# (2)多个参数:[["张三", "18"], ["李四", "19"], ["王五", "20"]]
# (3)JSON格式读取,每一组参数以对象形式存储:
# [
# {"name":"张三", "age":"18"},
# {"name":"李四", "age":"19"},
# {"name":"王五", "age":"20"}
# ]
# 单一参数时无需使用unpack,多参数需要使用unpack解包,注意json文件格式字符串用双引号
import ddt
import unittest
import json#方式1:非正式json格式使用
def read_dict_json():return json.load(open('dict.json', 'r', encoding='utf-8')) # 使用json包读取json文件,并作为返回值返回#方式2:JSON格式读取,提取已读完后的json文件(字典形式),通过遍历获取元素,并返回
def read_dict_json():lis = []dic = json.load(open('dict.json', 'r', encoding='utf-8'))# 此处加上遍历获取语句,下文yaml格式有实例,方法一样for item in dic:lis.append(item)return lis@ddt.ddt
class BasicTestCase(unittest.TestCase):@ddt.data(*read_dict_json())@ddt.unpack # 使用@unpack装饰器解包def test(self, name, age): # 因为是非规范json格式,所以形参名无限制,下文会解释规范json格式print('姓名:', name, '年龄:', age)#5、多参数yaml
# 以对象形式存储yml数据(字典)
# yaml格式文件内容
# -
# name: 张三
# age: 18
# -
# name: 李四
# age: 19
# -
# name: 王五
# age: 20
# '-'号之后一定要打空格!!!
# ':'号之后一定要打空格!!!# 入口参数与数据参数key命名统一即可导入
import ddt
import unittest
import yaml
@ddt.ddt
class BasicTestCase(unittest.TestCase):#方式1:形参入口和数据参数key命名统一@ddt.file_data('./data/dict.yml')def test(self, name, age): # 设置入口参数名字与数据参数命名相同即可print('姓名是:', name, '年龄为:', age)#方式2:入口参数与数据参数命名不统一@ddt.file_data('./data/dict.yml')def test(self, **cdata): # Python中可变参数传递的知识:**按对象顺序执行print('姓名是:', cdata['name'], '年龄为:', cdata['age']) # 通过对象访问语法即可调用
例子如下:
方式一:测试数据直接写成列表形式,使用ddt.data(*Data)传值
##2.12.2 DDT在自动化测试中的应用(传列表)import ddt
import unittest# 给4条测试数据Testdata = [{"username": "admin", "password": "123456", "excepted": {'code': '200', 'msg': '登录成功'}},{"username": None, "password": "1234567", "excepted": {'code': '400', 'msg': '用户名或密码不能为空'}},{"username": "admin", "password": None, "excepted": {'code': '400', 'msg': '用户名或密码不能为空'}},{"username": "admin", "password": "123456789", "excepted": {'code': '404', 'msg': '用户名或密码错误'}},]
@ddt.ddt
class TestModules(unittest.TestCase):def setUp(self):print('testcase beaning....')def tearDown(self):print('testcase ending.....')@ddt.data(*Data)def test_DataDriver(self,Data):#print('DDT数据驱动实战演示:',Testdata)res = login.login_check(Testdata['username'], Testdata['password'])self.assertEqual(res, Testdata['excepted'])
if __name__ == '__main__':unittest.main()
方式二:数据写到方法形式readData(),使用ddt.data(*readData())传值
import ddt
import unittest# 给4条测试数据
def readData():Testdata = [{"username": "admin", "password": "123456", "excepted": {'code': '200', 'msg': '登录成功'}},{"username": None, "password": "1234567", "excepted": {'code': '400', 'msg': '用户名或密码不能为空'}},{"username": "admin", "password": None, "excepted": {'code': '400', 'msg': '用户名或密码不能为空'}},{"username": "admin", "password": "123456789", "excepted": {'code': '404', 'msg': '用户名或密码错误'}},]return TestData@ddt.ddt
class TestModules(unittest.TestCase):def setUp(self):print('testcase beaning....')def tearDown(self):print('testcase ending.....')@ddt.data(*readData())def test_DataDriver(self,Data):#print('DDT数据驱动实战演示:',Testdata)res = login.login_check(Testdata['username'], Testdata['password'])self.assertEqual(res, Testdata['excepted'])
if __name__ == '__main__':unittest.main()
相关文章:
Python Unittest ddt数据驱动
1、数据驱动介绍: ddt.ddt(类装饰器,申明当前类使用ddt框架)ddt.data(函数装饰器,用于给测试用例传递数据),支持传python所有数据类型:数字(int,…...
Vue自定义组件遇到分页传输数据不正确解决办法
测试环境 Vue3 Element Plus 遇到问题 <el-table:data"tableData">...其他el-table-column<template #default"scope">// 自定义组件<my-button name"编辑" :id"scope.row.id"/ ></template></el-table&…...

ABAP 辨析CO|CN|CA|NA|CS|NS|CP|NP
1、文档说明 本篇文档将通过举例,解析字符的比较运算符之间的用法和区别,涉及到的操作符:CO|CN|CA|NA|CS|NS|CP|NP 2、用法和区别 用法总览 以下举例,几乎都使用一个字符变量和一个硬编码字符进行对比的方式,忽略尾…...

RK3568平台开发系列讲解(设备驱动篇)Pinctrl子系统详解
🚀返回专栏总目录 文章目录 一、pinctrl子系统结构描述二、重要的概念三、主要的数据结构和接口沉淀、分享、成长,让自己和他人都能有所收获!😄 📢我们知道在许多soc内部包含有多个pin控制器,通过pin控制器的寄存器,我们可以配置一个或者一组引脚的功能和特性。Linux…...

ROS小车研究笔记:二维SLAM建图简介与源码分析
ROS提供了现成的各类建图算法实现。如果只是应用的话不需要了解详细算法原理,只需要了解其需要的输入输出即可。 1 Gmapping Gmapping使用粒子滤波算法进行建图,在小场景下准确度高,但是在大场地中会导致较大计算量和内存需求 Gmapping需要…...

番外9:使用ADS对射频功率放大器进行非线性测试1(以IMD3测试为例)
番外9:使用ADS对射频功率放大器进行非线性测试1(以IMD3测试为例) 一般可以有多种方式对射频功率放大器的非线性性能进行测试,包括IMD3、ACPR、ACLR等等,其中IMD3的实际测试较为简单方便不需要太多的仪器。那么在ADS中…...
车载软件背景(留坑)
目前,车载软件已经成为汽车电子系统中不可或缺的一部分。随着汽车制造商不断增加车载软件的功能和性能,车载软件的市场规模也在不断扩大。据市场研究公司 Grand View Research 预测,到2025年,全球车载软件市场规模将达到190亿美元…...

Hadoop-MapReduce
Hadoop-MapReduce 文章目录Hadoop-MapReduce1 MapRedcue的介绍1.1 MapReduce定义1.2 MapReduce的思想1.3MapReduce优点1.4MapReduce的缺点1.5 MapReduce进程1.6 MapReduce-WordCount1.6.1 job的讲解2 Hadoop序列化2.1 序列化的定义2.2 hadoop序列化和java序列化的区别3 MapRedu…...

ChatGPT来了,软件测试工程师距离失业还远吗?
小伙伴们前一段是不是都看到过ChatGPT的相关视频,那它到底是什么?对软件测试行业会有什么影响? 今天汇智妹就用一篇文章来给大家讲清楚。 一、ChatGPT是什么? 简单来说,ChatGPT是一款人工智能聊天机器人,…...
【项目实战】Linux服务管理 之 开启/关闭防火墙
一、service命令是什么? service命令用于对系统服务进行管理,比如 启动(start)停止(stop)重启(restart)查看状态(status) service命令本身是一个shell脚本…...

OSS存储使用之centOS系统ossfs挂载
以CentOS7系统为例 下载CentOS系统支持的ossfs工具的版本,以下载CentOS 7.0 (x64)版本为例,可以通过wget命令进行安装包的下载 wget http://gosspublic.alicdn.com/ossfs/ossfs_1.80.6_centos7.0_x86_64.rpm 也可以通过yum命令来进行安装包的下载 sud…...
【项目实战】SpringBoot多环境(dev、test、prod)配置
一、三套环境介绍 1.1 开发环境(dev) 开发环境是程序猿们专门用于开发的服务器,配置可以比较随意 为了开发调试方便,一般打开全部错误报告。 1.2 测试环境(test) 一般是克隆一份生产环境的配置 一个程序在测试环境工作不正常,那么肯定不能把它发布到生产机上。 有些…...

Laravel框架01:composer和Laravel简介
Laravel框架01:composer和Laravel简介一、Composer介绍二、创建Laravel项目三、Laravel目录结构四、Laravel启动方式一、Composer介绍 composer 是PHP中用来管理依赖关系的工具。类似于Javascript的NPM。composer官网:https://getcomposer.org/安装结束…...

【bug】Transformer输出张量的值全部相同?!
【bug】Transformer输出张量的值全部相同?!现象原因解决现象 输入经过TransformerEncoderLayer之后,基本所有输出都相同了。 核心代码如下, from torch.nn import TransformerEncoderLayer self.trans TransformerEncoderLayer…...

【LeetCode】剑指 Offer(8)
目录 题目:剑指 Offer 21. 调整数组顺序使奇数位于偶数前面 - 力扣(Leetcode) 题目的接口: 解题思路: 代码: 过啦!!! 题目:剑指 Offer 24. 反转链表 - …...

安装MySQL数据库
安装MySQL数据库 获取软件:https://dev.mysql.com/downloads/mysql/ 下载完成后进行解压操作 若安装目录里没有my.ini配置文件,则需要新建一个my.ini的配置文件。 编辑my.ini配置文件,将配置文件中的内容修改成下面内容 [client] # 设置…...

手写Android性能监测工具,支持Fps/流量/内存/启动等
App性能如何量化:如何衡量一个APP性能好坏?直观感受就是:启动快、流畅、不闪退、耗电少等感官指标,反应到技术层面包装下就是:FPS(帧率)、界面渲染速度、Crash率、网络、CPU使用率、电量损耗速度等…...
Java知识复习(三)Java IO
1、IO流 IO流:数据传输过程类似于水流,故称IO流 IO流的的40多个类都是从4个抽象类基类中派生出来的,前者是字节,后者是字符 InputStream/Reader:所有的输入流的基类OutputStream/Writer:所有输出流的基类 2、字符流和字节流的区…...
Java版分布式微服务云开发架构 Spring Cloud+Spring Boot+Mybatis 电子招标采购系统功能清单
一、立项管理 1、招标立项申请 功能点:招标类项目立项申请入口,用户可以保存为草稿,提交。 2、非招标立项申请 功能点:非招标立项申请入口、用户可以保存为草稿、提交。 3、采购立项列表 功能点:对草稿进行编辑&#x…...
2023年全国最新会计专业技术资格精选真题及答案5
百分百题库提供会计专业技术资格考试试题、会计考试预测题、会计专业技术资格考试真题、会计证考试题库等,提供在线做题刷题,在线模拟考试,助你考试轻松过关。 1.某股份有限公司对外公开发行普通股2 000万股,每股面值为1元&#x…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...

Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲
文章目录 前言第一部分:体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分:体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...
深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏
一、引言 在深度学习中,我们训练出的神经网络往往非常庞大(比如像 ResNet、YOLOv8、Vision Transformer),虽然精度很高,但“太重”了,运行起来很慢,占用内存大,不适合部署到手机、摄…...

第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10+pip3.10)
第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10pip3.10) 一:前言二:安装编译依赖二:安装Python3.10三:安装PIP3.10四:安装Paddlepaddle基础框架4.1…...