【python】以souhu邮箱为例学习DDT数据驱动测试
前言
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数据驱动测试的更多相关文章
- 【python接口自动化】- DDT数据驱动测试
简单介绍 DDT(Date Driver Test),所谓数据驱动测试,简单来说就是由数据的改变从而驱动自动化测试的执行,最终引起测试结果的改变.通过使用数据驱动测试的方法,可以在需要验证多组数据 ...
- 如何快速掌握DDT数据驱动测试?
1.前言 (网盗概念^-^)相同的测试脚本使用不同的测试数据来执行,测试数据和测试行为完全分离, 这样的测试脚本设计模式称为数据驱动.(网盗结束)当我们测试某个网站的登录功能时,我们往往会使用不同的用 ...
- Python+Selenium笔记(十二):数据驱动测试
(一) 前言 通过使用数据驱动测试,实现对输入值和预期结果的参数化.(例如:输入数据和预期结果可以直接读取Excel文档的数据) (二) ddt 使用ddt执行数据驱动测试,ddt库可以将测试 ...
- python Unittest+excel+ddt数据驱动测试
#!user/bin/env python # coding=utf- # @Author : Dang # @Time : // : # @Email : @qq.com # @File : # @ ...
- python入门到精通[二]:基础学习(1)
摘要:Python基础学习: 注释.字符串操作.用户交互.流程控制.导入模块.文件操作.目录操作. 上一节讲了分别在windows下和linux下的环境配置,这节以linux为例学习基本语法.代码部分 ...
- Python之路,Day21 - 常用算法学习
Python之路,Day21 - 常用算法学习 本节内容 算法定义 时间复杂度 空间复杂度 常用算法实例 1.算法定义 算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的 ...
- 用Python实现gmail邮箱服务,实现两个邮箱之间的绑定(上)
一.本程序的起源 当我决定去中科院实习的时候,我给刘奎恩老师发了封邮件.我对此事是非常看重的,因此经常使用浏览器,打开gmail去查看刘老师有没有给我回复.因为gmail的新邮件推送的功能仅限于打开浏 ...
- 用Python实现gmail邮箱服务,实现两个邮箱之间的绑定(下)
一.我的需求 我希望做成具有以下功能的软件:1. 间隔一段时间登录我的邮箱查看是否有未读邮件 如果不断的运行查看是否有新邮件确实没多大必要. 另外如果这个客户端登录我的邮箱,那么我可能就不能用浏览器登 ...
- 用Python实现gmail邮箱服务,实现两个邮箱之间的绑定(中)
这篇博客,主要讲解用Python实现邮箱服务的几个需要学习的模块:E-mail Compotion and Decoding(邮件生成和解析).SMTP.POP.IMAP 如上篇博客所讲,我学习过程参 ...
随机推荐
- java中的swing设计界面时怎么加上背景图片。而不覆盖其他控件?
通过以下方式设置下背景就可以了: import java.awt.Container; import javax.swing.ImageIcon; import javax.swing.JFrame; ...
- javascript 标签轮播
html <div id="banner-switch"> <!-- 切换内容 --> <div class="notice-content ...
- java基础面试题(一)
1.java中的数据类型,各占多少个字节? 2.面向对象的特性 1-封装:简单来说,封装就是把数据和操作数据的方法绑定起来,如果需要访问,可以使用已定义的接口进行访问 2-继承:从已有的类得到继承信息 ...
- ubuntu18.04 kuebadm 安装 k8s-1.15.9
ubuntu kubeadm 搭建kubernetes1.15.9 准备 update && 安装docker apt-get update apt install docker 修改 ...
- 记一次centos挂载ceph存储的坑
起因 生产有两台服务器,准备用来跑工作流,执行的资源的是放在ceph存储集群中,第一步挂载ceph 执行命令:mount -t ceph xxx:xxx -o name=admin,secret=AQ ...
- Vite插件开发纪实:vite-plugin-monitor(上)
背景 最近在webpack项目里接入了Vite(dev mode),为开发提效.效果是真的猛. 项目启动速度提升70%-80%,HMR直接碾压webpack dev server 为了更加精准的计算收 ...
- GoLang设计模式08 - 命令模式
命令模式是一种行为型模式.它建议将请求封装为一个独立的对象.在这个对象里包含请求相关的全部信息,因此可以将其独立执行. 在命令模式中有如下基础组件: Receiver:唯一包含业务逻辑的类,命令对象会 ...
- oeasy教您玩转vim - 53 - # 批量替换
查找细节 回忆上节课内容 我们温习了关于搜索的相关内容 /正向,?反向 n保持方向,N改变方向 可以设置 是否忽略大写小写 是否从头开始查找 是否高亮显示 还有一些正则表达式的使用方法 行头行尾 ^$ ...
- Dart 中的final 和 const
Dart 常量和常量值 final 和 const 两个关键字用来定义常量,有什么区别呢? final 声明的是运行时常量,const声明的是编译时常量 const 可以声明常量值 举个例子: imp ...
- 低代码BPM平台
为了做出明智的决策并为客户提供服务,员工需要在正确的环境中使用正确的工具和访问关键信息的权限.但是,当业务关键信息分散在多个现成的和自定义编码的应用程序中时,员工效率会降低,客户体验也会受到影响. 低 ...