前言

DDT(Data-Driven Tests)是针对 unittest 单元测试框架设计的扩展库。允许使用不同的测试数据来运行一个测试用例,并将其展示为多个测试用例。通俗理解为相同的测试脚本使用不同的测试数据来执行,测试数据和测试行为完全分离, 这样的测试脚本设计模式称为数据驱动。相同的测试脚本使用不同的测试数据来执行,测试数据和测试行为完全分离, 这样的测试脚本设计模式称为数据驱动。


实施数据驱动步骤

我们再来说说实施数据驱动测试的步骤:

1.创建/准备测试数据

2.封装读取数据的方法,保留测试脚本调用的接口/属性(我们需要传递给脚本什么参数)

3.编写自动化测试脚本

4.脚本中调用封装好的处理数据文件的模块并引入测试数据

5.执行测试脚本并分析测试结果


数据驱动测试环境准备

GitHub 地址:https://github.com/datadriventests/ddt。
DDT 支持 pip 安装:pip install ddt

测试步骤

1.访问地址:https://mail.sohu.com/fe/#/login

2.输入用户名和密码

3.点击登录按钮

4.判断是否登录成功


数据存储

方法1:数据存在当前脚本中

 1 # -*- coding:GBK -*-
2 # 导入测试所需模块
3 import time
4 import unittest
5 from selenium import webdriver
6 from ddt import ddt, data, unpack
7 from selenium.common.exceptions import NoSuchElementException
8
9 """
10 简单额数据驱动测试
11 """
12 @ddt #@ddt来装饰测试类(ddt数据驱动的规范写法,记住就ok)
13 class DDT_TEST(unittest.TestCase):
14 # 数据可以是元祖、列表、字典
15 value =[['13691579846@sohu.com', 'xiaochao11520','https://mail.sohu.com/fe/#/homepage'],
16 ['13691579844@sohu.com', 'xiaochao11520','https://mail.sohu.com/fe/#/homepage']]
17
18 def setUp(self):
19 self.driver = webdriver.Firefox()
20 self.login_url = 'https://mail.sohu.com/fe/#/login'
21 self.driver.get(self.login_url)
22
23 @data(*value) # 解析数据
24 @unpack # 用来解包, 将每组数据的第一个数据传递给uname依次类推, 当数据为字典时,形参需和字段的key值相同
25 def test_case1(self, uname, passwd, expected):
26 try:
27 username = self.driver.find_element_by_xpath("//input[@placeholder='请输入您的邮箱']")
28 username.send_keys(uname)
29 time.sleep(2)
30 userpassword = self.driver.find_element_by_xpath("//input[@placeholder='请输入您的密码']")
31 userpassword.send_keys(passwd)
32 time.sleep(2)
33 self.driver.find_element_by_xpath("//input[@type='submit']").click()
34 time.sleep(2)
35 currenturl = self.driver.current_url
36 self.assertEqual(expected, currenturl, '登录失败')
37 except NoSuchElementException as e:
38 print(e)
39 raise
40 except ArithmeticError:
41 print('期望值是{},实际值是{}'.format(expected, currenturl))
42 raise
43 except Exception:
44 raise
45
46 def tearDown(self):
47 self.driver.quit()
48 # pass
49
50
51 if __name__ == "__main__":
52 unittest.main(verbosity=2)

源码分析

1.@ddt来装饰测试类(ddt数据驱动的规范写法,记住就ok)

2.@data(*value)装饰测试用例(也是一种规范,这边又涉及到装饰器,不懂的可以百度或者看我之前的文章又介绍,这边不再赘述,一句话两句话也说不清楚)记住:*value作用是打散数据,比如上面代码是用一个大列表存储两个小列表存放数据的,那么*value会得到两个小列表,每个小列表是一组测试数据

3.@unpack 解析*value数据,会把两个小列表里面的每一个数据取出来分别传递给我们测试用例的形参

方式1缺点

存储大量数据时,需查看源代码,不利于脚本的维护


方法2:json或txt文件读取测试数据进行数据驱动测试

新建一个json文件(也可以是txt文件),将我们需要的两组测试数据以列表的形式写到json文件中,每组数据的每一项参数用相同的符号分割开(方便脚本读取数据)

{
"value1":"13691579846@sohu.com||xiaochao11520||https://mail.sohu.com/fe/#/homepage",
"value2":"13691579844@sohu.com||xiaochao11520||https://mail.sohu.com/fe/#/homepage"
}
 1 # -*- coding:GBK -*-
2 # 导入测试所需模块
3 import unittest
4 from time import sleep
5 from ddt import ddt, file_data
6 from selenium import webdriver
7 from HTMLTestRunner import HTMLTestRunner
8 from selenium.common.exceptions import NoSuchElementException
9
10 """
11 从文件中读取测试数据
12 """
13 @ddt # ddt装饰测试类
14 class TestJsonData(unittest.TestCase):
15
16 def setUp(self):
17 self.driver = webdriver.Firefox()
18 self.driver.get("https://mail.sohu.com/fe/#/login")
19
20 @file_data('json_data.json') # 读取文件的 文件中数据可以是一个列表,也可以是一个字典
21 def test_data(self, value):
22 uname,passwd,expected = tuple(value.strip().split("||")) # value是一个字符串
23 try:
24 username = self.driver.find_element_by_xpath('//input[@placeholder="请输入您的邮箱"]')
25 username.send_keys(uname)
26 sleep(2)
27 password = self.driver.find_element_by_xpath('//input[@placeholder="请输入您的密码"]')
28 password.send_keys(passwd)
29 sleep(2)
30 self.driver.find_element_by_xpath('//input[@type="submit"]').click()
31 sleep(2)
32 currenturl = self.driver.current_url
33 self.assertEqual(expected, currenturl, "登录失败")
34 except NoSuchElementException as e:
35 print(e)
36 raise
37 except AssertionError:
38 print("期望值是{},实际值是{}".format(expected, currenturl))
39 except Exception:
40 raise
41 def tearDown(self):
42 self.driver.quit()
43
44
45 if __name__ == "__main__":
46 unittest.main(verbosity=2)

源码分析

1.相对上个实例,这里使用了@file_data(文件路径), 参数必须是一个文件,这里是一个json文件, 数据可以是一个列表,也可以是一个字典

# 列表形式
[
"*******@sohu.com||xiaochao11520||https://mail.sohu.com/fe/#/homepage",
"*******@sohu.com||xiaochao11520||https://mail.sohu.com/fe/#/homepage"
]

2.测试用例接收的是一个字符串,需要对字符串进行处理,把用户名,密码,期望值解析出来

3.测试数据存在文件中,方便管理修改,添加数据,易于维护


总结

看了上面的实例对于步骤应该还算合理,下面是我在网上找到的数据驱动测试步骤(感觉比较官方!大家可以参考)

1.编写测试脚本, 脚本需要支持从程序对象, 文件,或者数据库读入数据。(个人观点:如果脚本先编写完,测试数据还未准备,后期还要做修改)

2.将测试脚本使用的测试数据存入程序对象,文件,或者数据库等外部介质中。(个人观点:这个阶段实为准备数据的阶段,也就是我们数据要存在哪里,理应放在第一步)

3.运行脚本过程中,循环调用存储在外部介质中的测试数据。(个人观点:这里要考虑我们如何读取,使用数据)

4.验证所有的测试结果是否符合预期结果

参考文章:https://www.cnblogs.com/linuxchao/p/linuxchao-ddt.html

【python】以souhu邮箱为例学习DDT数据驱动测试的更多相关文章

  1. 【python接口自动化】- DDT数据驱动测试

    简单介绍 ​ DDT(Date Driver Test),所谓数据驱动测试,简单来说就是由数据的改变从而驱动自动化测试的执行,最终引起测试结果的改变.通过使用数据驱动测试的方法,可以在需要验证多组数据 ...

  2. 如何快速掌握DDT数据驱动测试?

    1.前言 (网盗概念^-^)相同的测试脚本使用不同的测试数据来执行,测试数据和测试行为完全分离, 这样的测试脚本设计模式称为数据驱动.(网盗结束)当我们测试某个网站的登录功能时,我们往往会使用不同的用 ...

  3. Python+Selenium笔记(十二):数据驱动测试

    (一)   前言 通过使用数据驱动测试,实现对输入值和预期结果的参数化.(例如:输入数据和预期结果可以直接读取Excel文档的数据) (二)   ddt 使用ddt执行数据驱动测试,ddt库可以将测试 ...

  4. python Unittest+excel+ddt数据驱动测试

    #!user/bin/env python # coding=utf- # @Author : Dang # @Time : // : # @Email : @qq.com # @File : # @ ...

  5. python入门到精通[二]:基础学习(1)

    摘要:Python基础学习: 注释.字符串操作.用户交互.流程控制.导入模块.文件操作.目录操作. 上一节讲了分别在windows下和linux下的环境配置,这节以linux为例学习基本语法.代码部分 ...

  6. Python之路,Day21 - 常用算法学习

    Python之路,Day21 - 常用算法学习   本节内容 算法定义 时间复杂度 空间复杂度 常用算法实例 1.算法定义 算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的 ...

  7. 用Python实现gmail邮箱服务,实现两个邮箱之间的绑定(上)

    一.本程序的起源 当我决定去中科院实习的时候,我给刘奎恩老师发了封邮件.我对此事是非常看重的,因此经常使用浏览器,打开gmail去查看刘老师有没有给我回复.因为gmail的新邮件推送的功能仅限于打开浏 ...

  8. 用Python实现gmail邮箱服务,实现两个邮箱之间的绑定(下)

    一.我的需求 我希望做成具有以下功能的软件:1. 间隔一段时间登录我的邮箱查看是否有未读邮件 如果不断的运行查看是否有新邮件确实没多大必要. 另外如果这个客户端登录我的邮箱,那么我可能就不能用浏览器登 ...

  9. 用Python实现gmail邮箱服务,实现两个邮箱之间的绑定(中)

    这篇博客,主要讲解用Python实现邮箱服务的几个需要学习的模块:E-mail Compotion and Decoding(邮件生成和解析).SMTP.POP.IMAP 如上篇博客所讲,我学习过程参 ...

随机推荐

  1. Elasticsearch -head 查询报 406错误码

    问题:利用Elasticsearch -head插件不能查看数据或者在Elasticsearch -linux的curl命令操作时总是提示: {"error":"Cont ...

  2. 一生挚友redo log、binlog《死磕MySQL系列 二》

    系列文章 原来一条select语句在MySQL是这样执行的<死磕MySQL系列 一> 一生挚友redo log.binlog<死磕MySQL系列 二> 前言 咔咔闲谈 上期根据 ...

  3. 为什么Charles中的中文展示成数字、英文字符串

    在使用charles抓包时,可能非看到如下图的字符串: 为什么会出现这样的字符串? 我们看到的汉字.字母,对电脑来说并不长这样,而是用二进制表示的(显然--),为了统一标准,老外发明了"字符 ...

  4. Django整理(一) - 项目和应用创建及运行

    一.项目组织结构     · 一个Project包含有多个App     · 一个App就是一个Python包,就代表一个功能模块,比如: 用户模块,商品模块等 .各个功能模块间可以保持相对的独立 . ...

  5. 使用CEF(四)— 在QT中集成CEF(1):基本集成

    QT作为C++下著名的跨平台软件开发框架,实现了一套代码可以在所有的操作系统.平台和屏幕类型上部署.我们前几篇文章讲解了如何构建一款基于CEF的简单的样例,但这些样例的GUI都是使用的原生的或者是控件 ...

  6. 牛逼的磁盘检查工具duf

    1.部署 wget https://github.com/muesli/duf/releases/download/v0.5.0/checksums.txt wget https://github.c ...

  7. 新版发布|ShardingSphere 5.0.0-beta 来了!

    Apache ShardingSphere 5.0.0-beta 版在经过长达半年的筹备后,终于将在近期正式 Release! 本文将带领大家一同预览新版本即将带来哪些重大亮点功能. 作者介绍 潘娟 ...

  8. Java秘诀!Java关系运算符介绍

    运算符丰富是 Java 语言的主要特点之一,它提供的运算符数量之多,在高级语言中是少见的. Java 语言中的运算符除了具有优先级之外,还有结合性的特点.当一个表达式中出现多种运算符时,执行的先后顺序 ...

  9. 【Azure 应用服务】App Service中运行Python 编写的 Jobs,怎么来安装Python包 (pymssql)呢?

    问题描述 在App Service中运行Python编写的定时任务,需要使用pymssql连接到数据库,但是发现使用 python.exe -m pip install --upgrade -r re ...

  10. Golang通脉之方法

    方法和接收者 Go语言中的方法(Method)是一种作用于特定类型变量的函数.这种特定类型变量叫做接收者(Receiver).接收者的概念就类似于其他语言中的this或者 self. Go 语言中同时 ...