当前位置: 首页 > news >正文

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

RK3568平台开发系列讲解(设备驱动篇)Pinctrl子系统详解

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

ROS小车研究笔记:二维SLAM建图简介与源码分析

ROS提供了现成的各类建图算法实现。如果只是应用的话不需要了解详细算法原理&#xff0c;只需要了解其需要的输入输出即可。 1 Gmapping Gmapping使用粒子滤波算法进行建图&#xff0c;在小场景下准确度高&#xff0c;但是在大场地中会导致较大计算量和内存需求 Gmapping需要…...

番外9:使用ADS对射频功率放大器进行非线性测试1(以IMD3测试为例)

番外9&#xff1a;使用ADS对射频功率放大器进行非线性测试1&#xff08;以IMD3测试为例&#xff09; 一般可以有多种方式对射频功率放大器的非线性性能进行测试&#xff0c;包括IMD3、ACPR、ACLR等等&#xff0c;其中IMD3的实际测试较为简单方便不需要太多的仪器。那么在ADS中…...

车载软件背景(留坑)

目前&#xff0c;车载软件已经成为汽车电子系统中不可或缺的一部分。随着汽车制造商不断增加车载软件的功能和性能&#xff0c;车载软件的市场规模也在不断扩大。据市场研究公司 Grand View Research 预测&#xff0c;到2025年&#xff0c;全球车载软件市场规模将达到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的相关视频&#xff0c;那它到底是什么&#xff1f;对软件测试行业会有什么影响&#xff1f; 今天汇智妹就用一篇文章来给大家讲清楚。 一、ChatGPT是什么&#xff1f; 简单来说&#xff0c;ChatGPT是一款人工智能聊天机器人&#xff0c;…...

【项目实战】Linux服务管理 之 开启/关闭防火墙

一、service命令是什么&#xff1f; service命令用于对系统服务进行管理&#xff0c;比如 启动&#xff08;start&#xff09;停止&#xff08;stop&#xff09;重启&#xff08;restart&#xff09;查看状态&#xff08;status&#xff09; service命令本身是一个shell脚本…...

OSS存储使用之centOS系统ossfs挂载

以CentOS7系统为例 下载CentOS系统支持的ossfs工具的版本&#xff0c;以下载CentOS 7.0 (x64)版本为例&#xff0c;可以通过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&#xff1a;composer和Laravel简介一、Composer介绍二、创建Laravel项目三、Laravel目录结构四、Laravel启动方式一、Composer介绍 composer 是PHP中用来管理依赖关系的工具。类似于Javascript的NPM。composer官网&#xff1a;https://getcomposer.org/安装结束…...

【bug】Transformer输出张量的值全部相同?!

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

【LeetCode】剑指 Offer(8)

目录 题目&#xff1a;剑指 Offer 21. 调整数组顺序使奇数位于偶数前面 - 力扣&#xff08;Leetcode&#xff09; 题目的接口&#xff1a; 解题思路&#xff1a; 代码&#xff1a; 过啦&#xff01;&#xff01;&#xff01; 题目&#xff1a;剑指 Offer 24. 反转链表 - …...

安装MySQL数据库

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

手写Android性能监测工具,支持Fps/流量/内存/启动等

App性能如何量化:如何衡量一个APP性能好坏&#xff1f;直观感受就是&#xff1a;启动快、流畅、不闪退、耗电少等感官指标&#xff0c;反应到技术层面包装下就是&#xff1a;FPS&#xff08;帧率&#xff09;、界面渲染速度、Crash率、网络、CPU使用率、电量损耗速度等&#xf…...

Java知识复习(三)Java IO

1、IO流 IO流&#xff1a;数据传输过程类似于水流&#xff0c;故称IO流 IO流的的40多个类都是从4个抽象类基类中派生出来的&#xff0c;前者是字节&#xff0c;后者是字符 InputStream/Reader:所有的输入流的基类OutputStream/Writer:所有输出流的基类 2、字符流和字节流的区…...

Java版分布式微服务云开发架构 Spring Cloud+Spring Boot+Mybatis 电子招标采购系统功能清单

一、立项管理 1、招标立项申请 功能点&#xff1a;招标类项目立项申请入口&#xff0c;用户可以保存为草稿&#xff0c;提交。 2、非招标立项申请 功能点&#xff1a;非招标立项申请入口、用户可以保存为草稿、提交。 3、采购立项列表 功能点&#xff1a;对草稿进行编辑&#x…...

2023年全国最新会计专业技术资格精选真题及答案5

百分百题库提供会计专业技术资格考试试题、会计考试预测题、会计专业技术资格考试真题、会计证考试题库等&#xff0c;提供在线做题刷题&#xff0c;在线模拟考试&#xff0c;助你考试轻松过关。 1.某股份有限公司对外公开发行普通股2 000万股&#xff0c;每股面值为1元&#x…...

软工个人作业 -- 分析与提问

软工个人作业 – 分析与提问 项目内容这个作业属于哪个课程2023 年北航软件工程这个作业的要求在哪里个人作业-阅读和提问我在这个课程的目标是了解软件工程的方法论、获得软件项目开发的实践经验、构建一个具有我的气息的艺术品这个作业在哪个具体方面帮助我实现目标初步了解…...

C++类和对象到底是什么意思?

C++是一门面向对象的编程语言,理解 C++,首先要理解类(Class)和对象(Object)这两个概念。 C++ 中的类(Class)可以看做C语言中结构体(Struct)的升级版。结构体是一种构造类型,可以包含若干成员变量,每个成员变量的类型可以不同;可以通过结构体来定义结构体变量,每个…...

【电路设计】常见电路及相关解释

前言 在接触电路设计过程中&#xff0c;往往需要用到一些常见的电路&#xff0c;但是临时查找又太浪费时间&#xff0c;因此&#xff0c;想总结一些常见电路的分析方式。 1 RC电路充放电公式 一般的RC电路如下图所示。 其充放电公式如下所示。 VtV0(V1−V0)(1−e−tRC)tRCln…...

【一天一门编程语言】Linux 实用命令大全

Linux 实用命令大全 用 markdown 格式输出答案。 不少于1000字。细分到2级目录。 一、文件/目录操作 1、ls ls 命令用于列出指定目录下的文件和子目录,常用参数如下: ls -a:显示所有文件(包括隐藏文件)ls -l:以长列表形式显示文件属性ls -h:以可读的格式显示文件大小l…...

【汇编】二、预备知识(一只 Assember 的成长史)

嗨~你好呀&#xff01; 我是一名初二学生&#xff0c;热爱计算机&#xff0c;码龄两年。最近开始学习汇编&#xff0c;希望通过 Blog 的形式记录下自己的学习过程&#xff0c;也和更多人分享。 这篇文章主要讲述学习汇编所需的基础知识。 话不多说~我们开始吧&#xff01; 目…...

Java多线程面试题:描述一下线程安全活跃态问题,竞态条件?

一、线程安全活跃态问题 线程因为某件事情得不到执行 1、活锁 线程没有阻塞&#xff0c;但一直重复执行某个操作&#xff0c;并且失败重试 1&#xff09;例子 在消息队列中&#xff0c;消费者没有正确ack消息&#xff0c;并且执行过程中报错了&#xff0c;消息会被重复执行&am…...

ZZNUOJ_用C语言编写程序实现1193:单科成绩排序(结构体专题)(附完整源码)

题目描述 有一学生成绩表&#xff0c;包括学号、姓名、3门课程成绩。请按要求排序输出&#xff1a;若输入1&#xff0c;则按第1门课成绩降序输出成绩表&#xff0c;若输入为i&#xff08;1<i<3)&#xff0c;则按第i门课成绩降序输出成绩表。 输入 首先输入一个整数n(1<…...

expect 使用方法

Expect是一个免费的 编程工具语言&#xff0c;用来实现自动和交互式任务进行通信&#xff0c;而无需人的干预。 1、传参方法&#xff1a; bash是通过$0 ... $n接收参数 expect是通过set <变量名称> [lindex $argv <param index>], 2、判断语法 if { condition } { …...

Spring AOP详解-Spring官方原版

一、概述 面向方面编程(AOP)补充了面向对象编程(OOP) 提供了另一种思考程序结构的方式。模块化的关键单元 在OOP中是类,而在AOP中,模块化的单位是方面。方面 实现跨越问题(如事务管理)的模块化 多种类型和对象。(这种关切通常被称为“跨领域”关切 Spring 的关键组件之…...

链表习题精选(持续更新中)

第一题给定单链表的头节点 head &#xff0c;将所有索引为奇数的节点和索引为偶数的节点分别组合在一起&#xff0c;然后返回重新排序的列表。第一个节点的索引被认为是 奇数 &#xff0c; 第二个节点的索引为 偶数 &#xff0c;以此类推。请注意&#xff0c;偶数组和奇数组内部…...