python 基于DDT实现数据驱动测试


Posted in Python onFebruary 18, 2021

简单介绍

​ DDT(Date Driver Test),所谓数据驱动测试,简单来说就是由数据的改变从而驱动自动化测试的执行,最终引起测试结果的改变。通过使用数据驱动测试的方法,可以在需要验证多组数据测试场景中,使用外部数据源实现对输入输出与期望值的参数化,避免在测试中使用硬编码的数据,也就是测试数据和用例脚本代码分离。

​ DDT它其实就是一个装饰器,它会根据你传递进来的数据来决定要生成几个测试用例。

​ ?使用的意义

1.代码复用率高:一个测试逻辑只需要写一次,可以多条测试数据复用,同时提高测试脚本的编写效率。

2.异常排查效率高:根据测试数据,每条数据生成一条测试用例,用例相互分离,一条失败的情况下不会影响其他测试用例。

3.代码可维护性高:简洁明了的测试框架,利于其他同事阅读,提高代码的可维护性。

安装及导入

​ cmd命令行执行安装:pip install ddt

​ 直接导入到模块:import ddt,或导入具体的装饰器:from ddt import ddt, data, unpack

使用详解

​ ?三个要点:

  • @ddt:装饰测试类
  • @data:装饰测试用例
  • @unpack:装饰测试用例

​ 要使用ddt的前提是要有测试用例类,然后用@ddt去装饰测试用例类,用@data(测试数据)去装饰测试用例,如下登录接口例子:

from ddt import ddt, data
from common.read_excel import ReadExcel
from common.my_logger import log


@ddt # 装饰登录测试用例类,声明使用ddt
class LoginTestCase(unittest.TestCase):
  
  excel = ReadExcel("cases.xlsx", "login")
  cases = excel.read_data()
  
  @data(*cases)	# 装饰测试用例
  def test_login(self, case):
    case_data = eval(case["data"])
    expected = eval(case["expected"])
    case_id = case["case_id"]
    result = login_check(*case_data)
    response = self.http.send(url=url, method=method, json=data, headers=headers)
    result = response.json()
    try:
      self.assertEqual(expected["code"], result["code"])
      self.assertEqual((expected["msg"]), result["msg"])
    except AssertionError as e:
      log.info("用例:{}--->执行未通过".format(case["title"]))
      print("预期结果:{}".format(expected))
      print("实际结果:{}".format(result))
      raise e
    else:
      log.info("用例:{}--->执行通过".format(case["title"]))


if __name__ == '__main__':
  unittest.main()

@ddt它做的事情其实就等同于这句代码:LoginTestCase = ddt(LoginTestCase),把具体的类名传给ddt,告诉ddt是这个测试用例类要使用数据驱动。

@data做的事情就是把测试数据作为一个参数传递给测试用例,一个数据对应生成一条测试用例,如果data里面有多个数据那么就对应生成多条测试用例。如果data里放的类似是元组、列表等这样的序列类型的数据,data会把他们当成是一个整体,即一个测试数据。

​ 如果想一次传递多个参数给测试用例,需要自行在脚本中对数据进行分解或者使用@unpack分解数据。如上例子中的测试用例,只使用了一个参数,但这个参数case是一个字典,字典中已经包含多个数据,直接用key获取对应的值即可。@unpack则是可以把序列类型的数据拆分为多个,以多个参数传给测试用例,但测试用例也需要定义同等数量的参数来接收。

​ 上面例子的测试数据cases来源是使用了openpyxl来读取excel中的测试数据的,关于openpyxl可以看我这个系列的另外一篇随笔。这里直接说明cases其实就是像下面这样的一个列表:

cases = [{'case_id': 1, 'title': '正常登录', 'data': '("test", "Test1234")', 'expected': '{"code": 0, "msg": "登录成功"}'}, {'case_id': 2, 'title': '密码错误', 'data': '("test", "123")', 'expected': '{"code": 1, "msg": "账号或密码不正确"}'}, {'case_id': 3, 'title': '账户名错误', 'data': '("test11", "Test1234")', 'expected': '{"code": 1, "msg": "账号或密码不正确"}'}]

# *解包后,一个字典就是一个测试用例数据
# 如第一个字典:{'case_id': 1, 'title': '正常登录', 'data': '("test", "Test1234")', 'expected': '{"code": 0, "msg": "登录成功"}'}

​ 通过*解包,它的数据就是3个字典,每次给测试用例传入1个字典,而这个字典里就存放了一条完整的登录接口测试用例的测试数据,包括用例id、用例标题、测试的账号密码、期望返回的结果。

​ ?小结:

  • @data(a,b):a和b各运行一次用例
  • @data(*(a,b):a和b各运行一次用例,使用*解包,相当于@data(a,b)
  • @data([a,d],[c,d])

                  如果没有@unpack[a,b]、[c,d]都会被当成一个参数传入用例,即用[a,b]运行一次,用[c,d]运行一次;
                  如果有@unpack,[a,b]会被分解开,一次传递两个参数给用例,用例需要定义两个参数接收
                  @unpack可适用元组、列表或字典,但当传入的是字典时,字典的key和用例定义的参数名需要保持一致

​ 关键代码:@file_data,传递文件(json/yaml)

扩展

​ 关键代码:@file_data,传递文件(json/yaml)

# 传递json
"""
json文件数据
{
	"token":123456,
	"actionName": "api.login",
	"content": {
		"user": "miki",
		"pwd": "Test123"
	}
}
"""
"""
yaml文件
test_list:
 - 11
 - 22
 - 12

sorted_list: [ 11, 12, 22 ]
"""
from ddt import *


@ddt	# 声明使用ddt
class TestFile(unittest.TestCase):

  @file_data('D:/test/test.json')
  def test_json(self, json_data):
    print(json_data)
    
  @file_data('D:/test/test.yaml')
  def test_yaml(self, yaml_data):
    print("yaml", yaml_data)

以上就是python 基于DDT实现数据驱动测试的详细内容,更多关于python 实现数据驱动测试的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
python数据结构树和二叉树简介
Apr 29 Python
Python2.x版本中maketrans()方法的使用介绍
May 19 Python
JSONLINT:python的json数据验证库实例解析
Nov 28 Python
基于Django的ModelForm组件(详解)
Dec 07 Python
PyQt5每天必学之日历控件QCalendarWidget
Apr 19 Python
浅谈Python在pycharm中的调试(debug)
Nov 29 Python
python实现坦克大战游戏 附详细注释
Mar 27 Python
django使用django-apscheduler 实现定时任务的例子
Jul 20 Python
python3安装OCR识别库tesserocr过程图解
Apr 02 Python
利用Python如何实时检测自身内存占用
May 09 Python
Python模拟登入的N种方式(建议收藏)
May 31 Python
python 如何把docker-compose.yaml导入到数据库相关条目里
Jan 15 Python
详解解决jupyter不能使用pytorch的问题
Feb 18 #Python
python 使用openpyxl读取excel数据
Feb 18 #Python
Python用SSH连接到网络设备
Feb 18 #Python
python 实现IP子网计算
Feb 18 #Python
详解python3 GUI刷屏器(附源码)
Feb 18 #Python
基于Python-turtle库绘制路飞的草帽骷髅旗、美国队长的盾牌、高达的源码
Feb 18 #Python
Python如何telnet到网络设备
Feb 18 #Python
You might like
星际争霸教主Flash的ID由来:你永远不会知道他之前的ID是www!
2019/01/18 星际争霸
PHP会话处理的10个函数
2015/08/11 PHP
TP5框架实现签到功能的方法分析
2020/04/05 PHP
JavaScript prototype对象的属性说明
2010/03/13 Javascript
jquery淡入淡出效果简单实例
2016/01/14 Javascript
jQuery绑定事件监听bind和移除事件监听unbind用法实例详解
2016/01/19 Javascript
JavaScript事件学习小结(三)js事件对象
2016/06/09 Javascript
js 动态给元素添加、移除事件的实现方法
2016/07/19 Javascript
Angular.JS利用ng-disabled属性和ng-model实现禁用button效果
2017/04/05 Javascript
ES6正则的扩展实例详解
2017/04/25 Javascript
浅谈Node.js轻量级Web框架Express4.x使用指南
2017/05/03 Javascript
JavaScript30 一个月纯 JS 挑战中文指南(英文全集)
2017/07/23 Javascript
微信小程序使用toast消息对话框提示用户忘记输入用户名或密码功能【附源码下载】
2017/12/09 Javascript
使用node.js实现微信小程序实时聊天功能
2018/08/13 Javascript
vue-cli 3.x配置跨域代理的实现方法
2019/04/12 Javascript
VUE实现图片验证码功能
2020/11/18 Javascript
jQuery 判断元素是否存在然后按需加载内容的实现代码
2020/01/16 jQuery
node.js使用zlib模块进行数据压缩和解压操作示例
2020/02/12 Javascript
JS实现时间校验的代码
2020/05/25 Javascript
使用Vue Composition API写出清晰、可扩展的表单实现
2020/06/10 Javascript
Vue+Java 通过websocket实现服务器与客户端双向通信操作
2020/09/22 Javascript
vue使用vue-quill-editor富文本编辑器且将图片上传到服务器的功能
2021/01/13 Vue.js
[02:38]DOTA2英雄基础教程 噬魂鬼
2014/01/03 DOTA
python中numpy基础学习及进行数组和矢量计算
2017/02/12 Python
Python使用pymongo模块操作MongoDB的方法示例
2018/07/20 Python
Python读写zip压缩文件的方法
2018/08/29 Python
python实现在一个画布上画多个子图
2020/01/19 Python
10个python3常用排序算法详细说明与实例(快速排序,冒泡排序,桶排序,基数排序,堆排序,希尔排序,归并排序,计数排序)
2020/03/17 Python
如何学习Python time模块
2020/06/03 Python
python Scrapy爬虫框架的使用
2021/01/21 Python
html5 canvas移动浏览器上实现图片压缩上传
2016/03/11 HTML / CSS
尽职尽责村干部自我鉴定
2014/01/23 职场文书
工作保证书怎么写
2015/02/28 职场文书
2015年国庆节演讲稿范文
2015/07/30 职场文书
Python面向对象之成员相关知识总结
2021/06/24 Python
MySQL中rank() over、dense_rank() over、row_number() over用法介绍
2022/03/23 MySQL