python之ddt模块使用
一、DDT(数据驱动)简介
Data-Driven Tests(DDT)即数据驱动测试,可以实现不同数据运行同一个测试用例(通过数据的不同来驱动测试结果的不同)。
ddt本质其实就是装饰器,一组数据一个场景。
ddt模块包含了一个类的装饰器ddt(@ddt)和三个方法的装饰器(@data、@unpack、@file_data),其中:
@data:包含多个你想要传给测试用例的参数,可以为列表、元组、字典等;
@file_data:会从json或yaml中加载数据;
(注意,如果文件以”.yml”或者”.yaml”结尾,ddt会作为yaml类型处理,其他所有文件都会作为json文件处理。如txt文件)
@unpack:分割元素。
(需要搭配unittest测试框架使用,实现数据驱动测试)
数据驱动测试:
1、避免编写重复代码
2、数据与测试脚本分离
3、通过使用数据驱动测试,来验证多组数据测试场景
通常来说,多用于单元测试和接口测试
1、传递列表、字典等数据
# get_ddt.py import unittest
from ddt import ddt, data, unpack, file_data # 声明了ddt类装饰器
@ddt
class MyddtTest(unittest.TestCase): # @data方法装饰器
# 单组元素
@data(1,2,3)
def test_01(self, value): # value用来接受data的数据
print(value) # 多组数据,未拆分
@data([1,2],[3,4])
def test_02(self, value):
print(value) # 多组数据,拆分
# @unpac拆分,相当于把数据的最外层结构去掉
@data([5,6],[7,8])
@unpack
def test_03(self, value1, value2):
print(value1, value2) # 单个列表字典,未拆分
@data([{"name": "peter", "age": 15, "addr": "chengdu"}])
def test_04(self, value):
print(value) # 多个列表字典,拆分
@data([{"name":"peter","age":16,"addr":"chengdu"},{"name":"lily","age":17,"addr":"chengdu"}])
@unpack
def test_05(self, value1, value2):
print(value1, value2) # 单个字典,拆分
# @data里的数据key必须与字典的key保持一致
@data({"name":"jack","age":20})
@unpack
def test_06(self, name, age):
print(name, age) # 多个字典, 拆分
@data({"name":"peter","age":18,"addr":"chengdu"},{"name":"lily","age":19,"addr":"chengdu"})
@unpack
def test_07(self, name, age, addr):
print(name, age, addr) # 多个列表字典,引用数据
testdata = [{"name": "peter", "age": 21, "addr": "chengdu"}, {"name": "lily", "age": 22, "addr": "chengdu"}]
@data(testdata)
@unpack
def test_08(self, value1, value2):
print(value1, value2) # @data(*testdata):*号意为解包,ddt会按逗号分隔,将数据拆分(不需要@unpack方法装饰器了)
testdata = [{"name":"peter","age":23,"addr":"chengdu"},{"name":"lily","age":24,"addr":"chengdu"}]
@data(*testdata)
def test_09(self, value):
print(value) if __name__ == "__main__":
unittest.main()
运行结果: ...................
----------------------------------------------------------------------
Ran 19 tests in 0.000s OK
1
2
3
[1, 2]
[3, 4]
5 6
7 8
[{'name': 'peter', 'age': 15, 'addr': 'chengdu'}]
{'name': 'peter', 'age': 16, 'addr': 'chengdu'} {'name': 'lily', 'age': 17, 'addr': 'chengdu'}
jack 20
peter 18 chengdu
lily 19 chengdu
{'name': 'peter', 'age': 21, 'addr': 'chengdu'} {'name': 'lily', 'age': 22, 'addr': 'chengdu'}
{'name': 'peter', 'age': 23, 'addr': 'chengdu'}
{'name': 'lily', 'age': 24, 'addr': 'chengdu'}
2、传递json、yaml文件
# config.json {
"stu1": {
"name": "Peter",
"age": 29,
"addr": "BeiJing"
},
"stu2": {
"name": "Jack",
"age": 30,
"addr": "ShenZhen"
}
}
# config.yaml # 使用-分隔用例,则yaml读取到的数据类型为列表
-
model: 注册模块
title: 注册成功
url: http://api.nnzhp.cn/api/user/user_reg
method: POST
data:
username: yingcr10
pwd: Ace123456
cpwd: Ace123456
check:
error_code: 0
msg: 注册成功!
-
model: 注册模块
title: 用户名长度小于6位,注册失败
url: http://api.nnzhp.cn/api/user/user_reg
method: POST
data:
username: yingc
pwd: Ace123456
cpwd: Ace123456
check:
error_code: 3002
# get_ddt.py import unittest
from ddt import ddt, data, unpack, file_data # 声明了ddt类装饰器
@ddt
class MyddtTest(unittest.TestCase): # @file_data加载json文件
# **testdata:将提取到的数据存放在空字典testdata中
@file_data("config.json")
def test_10(self, **testdata):
# 再从字典testdata中单独提取参数
name = testdata['name']
age = testdata['age']
addr = testdata['addr']
print(testdata)
print(name, age, addr) # 直接提取参数, test()方法中的参数必须与json文件中的键保持一致
@file_data("config.json")
def test_11(self,name, age, addr):
name = name
age = age
addr = addr
print(name, age, addr) # @file_data加载yaml文件
@file_data("config.yaml")
def test_12(self, model, title, url, method, data, check):
username = data['username']
pwd = data['pwd']
cpwd = data['pwd']
print(model, title, url, method, data, check)
print(username, pwd, cpwd) # **testdata:将提取到的数据存放在空字典testdata中
@file_data("config.yaml")
def test_13(self, **testdata):
# 再从字典testdata中单独提取参数
model = testdata['model']
title = testdata['title']
print(testdata)
print(model, title) if __name__ == "__main__":
unittest.main()
运行结果: ........
----------------------------------------------------------------------
Ran 8 tests in 0.000s OK
{'name': 'Peter', 'age': 29, 'addr': 'BeiJing'}
Peter 29 BeiJing
{'name': 'Jack', 'age': 30, 'addr': 'ShenZhen'}
Jack 30 ShenZhen
Peter 29 BeiJing
Jack 30 ShenZhen
注册模块 注册成功 http://api.nnzhp.cn/api/user/user_reg POST {'username': 'yingcr10', 'pwd': 'Ace123456', 'cpwd': 'Ace123456'} {'error_code': 0, 'msg': '注册成功!'}
yingcr10 Ace123456 Ace123456
注册模块 用户名长度小于6位,注册失败 http://api.nnzhp.cn/api/user/user_reg POST {'username': 'yingc', 'pwd': 'Ace123456', 'cpwd': 'Ace123456'} {'error_code': 3002}
yingc Ace123456 Ace123456
{'model': '注册模块', 'title': '注册成功', 'url': 'http://api.nnzhp.cn/api/user/user_reg', 'method': 'POST', 'data': {'username': 'yingcr10', 'pwd': 'Ace123456', 'cpwd': 'Ace123456'}, 'check': {'error_code': 0, 'msg': '注册成功!'}}
注册模块 注册成功
{'model': '注册模块', 'title': '用户名长度小于6位,注册失败', 'url': 'http://api.nnzhp.cn/api/user/user_reg', 'method': 'POST', 'data': {'username': 'yingc', 'pwd': 'Ace123456', 'cpwd': 'Ace123456'}, 'check': {'error_code': 3002}}
注册模块 用户名长度小于6位,注册失败
三、通过ddt读取yaml测试数据
config.yaml数据文件与上文的一致。
# get_ddt.py import requests
import unittest
import json
from ddt import ddt, data, unpack, file_data @ddt
class SignTest(unittest.TestCase): # 使用ddt加载yaml中的测试数据
@file_data("config.yaml")
def test_get_yaml(self,model,title,url,method,data,check):
# 提取分离各参数
model = model
title = title
url = url
method = method
data = data
check = check
self.sign_test(model,title,url,method,data,check) def sign_test(self,model,title,url,method,data,check):
print("模块: ", model)
print("用例标题: ", title)
response = requests.request(url=url, method=method, data=data).text
response = json.loads(response)
try:
# 通过断言,判断测试是否通过
assert check['error_code'] == response['error_code']
print("测试通过")
except Exception as e:
print("测试失败")
raise e if __name__ == "__main__":
unittest.main()
运行结果: 模块: 注册模块
用例标题: 注册成功
测试通过
模块: 注册模块
用例标题: 用户名长度小于6位,注册失败
测试通过
..
----------------------------------------------------------------------
Ran 2 tests in 0.188s OK
四、python中使用ddt+excel读取测试数据
大体思路:先从excel文件中读取数据,然后再用ddt加载已读取的数据。
# get_excel.py from openpyxl import load_workbook class ExcelData(): def __init__(self, file="config.xlsx"):
'''
初始化Excel对象
'''
self.file = file
self.wb = load_workbook(self.file) def get_row_value(self, row, sheet_name="Sheet1"):
'''
获取Excel中某一行的数据
'''
sh = self.wb[sheet_name]
max_col = sh.max_column
row_value = []
for col in range(1, max_col+1):
value = sh.cell(row, col).value
row_value.append(value)
return row_value def get_all_row(self, sheet_name="Sheet1"):
'''
获取Excel中所有行的数据,并存放在列表中
'''
sh = self.wb[sheet_name]
max_row = sh.max_row
row_value = []
for row in range(2, max_row+1):
value = self.get_row_value(row)
row_value.append(value)
return row_value if __name__ == "__main__":
excel = ExcelData()
testdata = excel.get_all_row()
print(testdata)
# get_ddt.py import requests
import unittest
from ddt import ddt, data, unpack, file_data
from get_excel import ExcelData @ddt
class SignTest(unittest.TestCase): # 从get_excel.py中读取测试数据
excel = ExcelData()
testdata = excel.get_all_row() @data(*testdata)
def test_sign(self, datas):
# 由于从excel中读取到的数据为列表形式,所以采用下标来提取各参数
ID = datas[0]
model = datas[1]
title = datas[2]
method = datas[3]
url = datas[4]
username = datas[5]
pwd = datas[6]
cpwd = datas[7]
check = datas[8]
body = {
"username": username,
"pwd": pwd,
"cpwd": cpwd
}
self.sign_test(ID,model,title,url,method,body,check) def sign_test(self,ID,model,title,url,method,body,check):
print("用例ID:", ID)
print("模块:", model)
print("用例标题:", title)
response = requests.request(url=url, method=method, data=body).text
try:
# 通过断言,比较实际结果是否与预期结果一致
# 由于从excel中读取到的check为str类型,所以response不用转换为dict,直接断言比较是否相等
assert check == response
print("测试通过")
except Exception as e:
print("测试失败")
raise e if __name__ == "__main__":
unittest.main()
运行结果: 用例ID: 001
模块: 注册模块
用例标题: 正确的用户名和密码,注册成功
.测试通过
用例ID: 002
模块: 注册模块
用例标题: 用户名长度小于6位,注册失败
.测试通过
OK
----------------------------------------------------------------------
Ran 2 tests in 0.190s Process finished with exit code 0
参考:http://www.manongjc.com/detail/18-eosubecmlglohgb.html
python之ddt模块使用的更多相关文章
- python使用ddt模块对用例执行操作
import time import unittest import ddt from selenium import webdriver TEST_URL = "http://www.ba ...
- python ddt模块
ddt模块包含了一个类的装饰器ddt和两个方法的装饰器: data:包含多个你想要传给测试用例的参数: file_data:会从json或yaml中加载数据: 通常data中包含的每一个值都会作为一个 ...
- 【python+ddt】DDT模块的使用
ddt模块包含了一个类的装饰器ddt和两个方法的装饰器: data:包含多个你想要传给测试用例的参数: file_data:会从json或yaml中加载数据: unpanck:通常data中包含的每一 ...
- DDT模块
转自: https://www.cnblogs.com/frost-hit/p/8277637.html Python DDT(data driven tests)模块心得 关于ddt模块的一些心 ...
- Python 安装第三方模块时 报Retrying(Retry(total=4, connect=None, read=None, redirect=None, status=None))...[WinError 10061]由于目标计算机积极拒绝,无法连接 错误
今日在安装ddt模块时(Windows系统),cmd报了一个以前从未见过的错误,如下图所示: 经百度,知是镜像源的问题,将安装命令改成如下命令: pip install ddt -i https:// ...
- python之platform模块
python之platform模块 ^_^第三个模块从天而降喽!! 函数列表 platform.system() 获取操作系统类型,windows.linux等 platform.platform() ...
- python之OS模块详解
python之OS模块详解 ^_^,步入第二个模块世界----->OS 常见函数列表 os.sep:取代操作系统特定的路径分隔符 os.name:指示你正在使用的工作平台.比如对于Windows ...
- python之sys模块详解
python之sys模块详解 sys模块功能多,我们这里介绍一些比较实用的功能,相信你会喜欢的,和我一起走进python的模块吧! sys模块的常见函数列表 sys.argv: 实现从程序外部向程序传 ...
- 学习PYTHON之路, DAY 6 - PYTHON 基础 6 (模块)
一 安装,导入模块 安装: pip3 install 模块名称 导入: import module from module.xx.xx import xx from module.xx.xx impo ...
随机推荐
- asp.netcore3.1 将服务器配置为需要证书
运行 asp.netcore 3.1应用程序时,弹出证书选择框. 将服务器配置为需要证书(Kestrel),在Program.cs中,按如下所示配置 Kestrel: public static vo ...
- Python多进程实现并行化随机森林
文章目录 1. 前言 2. 随机森林原理 3.实现原理 3.1并行化训练 3.1.1训练函数 3.1.2 单进程训练函数 生成数据集模块--生成部分数据集 单进程训练函数代码 3.2 并行化预测 3. ...
- Android PopupWindow显示之后所在的Activity结束的时候出现短暂黑屏问题
在当前Activity弹出PopuoWindow后,点击取消弹窗,然后结束当前Activity时会出现短暂黑屏现象.这是由于设置背景透明度时候造成的. //设置添加屏幕的背景透明度 public vo ...
- Windows下nacos单机部分发现的坑
一.下载nacos的地址: https://github.com/alibaba/nacos/releases 下载 nacos-server-1.3.2.tar.gz 就好 二.在Window ...
- nohup 命令的使用
nohup 命令的使用 1. nohup简介 nohup 命令运行由 Command参数和任何相关的 Arg参数指定的命令,忽略所有挂断(SIGHUP)信号.在注销后使用 nohup 命令运行后台中的 ...
- JavaScript学习系列博客_4_JavaScript中的数据类型
JavaScript中有6种数据类型 一.基本数据类型 - String 字符串 JS中的字符串需要使用引号引起来双引号或单引号都行 但是要注意的是某种引号嵌套使用的话,需要加上 \ 转义.比如说我们 ...
- YouCompleteMe unavailable: requires Vim compiled with Python 2.x support
问题:YouCompleteMe unavailable: requires Vim compiled with Python 2.x support 解决:重新编译,加入--enable-pytho ...
- git使用小结(本地分支与远程分支、git命令)
git git 是一个版本管理系统(VCS),可以在任何时间点,将文档的状态作为一份更新记录保存起来,并且在任意的时间点,恢复更新记录 版本管理 版本管理是一种记录文件变化的方式,方便查阅特定版本号的 ...
- Dockerfile文件万字全面解析
阅读目录 目录 阅读目录 用法 格式 Parser directives escape 环境替换 .dockerignore file FROM RUN CMD LABEL MAINTAINER EX ...
- 技术揭秘:华为云DLI背后的核心计算引擎
摘要:介绍隐藏在华为云数据湖探索服务背后的核心计算引擎Spark,玩转DLI,,轻松完成大数据的分析处理. 本文主要给大家介绍隐藏在华为云数据湖探索服务(后文简称DLI)背后的核心计算引擎——Spar ...