1.什么是数据驱动?
数据驱动:是以数据来驱动整个测试用例的执行,也就是测试数据决定测试结果
比如我们要测试加法,我们的测试数据是1和1,测试结果是2,如果测试数据是1和2,测试结果是3
2.数据驱动的特点
1.数据驱动本身不是一个工业化标准的概念,因此在不同的公司会有不同的解释
2.可以把数据驱动理解成一种模式或一种思想
3.数据驱动技术可以将用户把关注点放在对测试数据的构建和维护上,而不是直接维护驱动,可以利用同样的过程对不同的数据输入进行测试
4.数据驱动的实现要依赖参数化的技术
3.传入数据的方式(测试数据的来源)
直接定义在测试脚本上(简单直观,但代码和数据来实现真正的分离,不方便后去维 护)
从文件读取数据(如:json,excel,xml,txt等格式文件)
从数据库中读取数据
直接调用接口获取数据源
本地封装一些生成数据的方法
4.JSON
特点
纯文本
具有良好的自我描述性,便于阅读和编写
具有清楚的层次结构
有效地提升网络传输效率
语法规则
对象数组可以互相嵌套
大括号保存对象
中括号保存数组
数据采用键值对表示
多个数据由逗号分隔
JSON值
JSON值可以是:
数字(整数/浮点数)
字符串(双引号中)
逻辑值(true/false)
数组(中括号中)
对象(大括号中)
None
5.数据操作
数据操作
python字典与JSON之间的转化 (需导包 import json)
JSON文件读写
将python字典转化为JSON字符串
import json
"""
操作:
1,导包:import json
2.调用dumps()方法 将python字典转化为json字符串
在json中,dump()方法是写入json
"""
"""将字符串转化为json字符串"""
data={
'id':1,
'name':"angleliu",
'address':"陕西省西安市",
'school':None
}
json_str= json.dumps(data)
print("data is ",data)
print(json_str)
把JSON字符串转化为python字典
''''将字符串转化为json'''
'''
方法:loads()将字符串转化为字典,load()该方法为读取json
注意:
'''
#定义字符串
#属性名必须是双引号,不可以用单引号 错误写法"{'name':'angleliu'}"
data='{"data":"angleliu","age":18}'
#转化
json_str=json.loads(data)
print("data is ",data)
print(json_str)
json文件读写
写入json文件
#写入操作
import json
param={"name":"tom","age":18}
with open('../case/data2.json','w',encoding='utf-8') as f:
data=json.dump(param,f)
# 写入操作
param = {"name": "刘阳", "age": 18}
with open('../case/data2.json', 'w', encoding='utf-8') as f:
#ctrl+p:查看dump中参数的设置,默认情况下ensure_ascii=True,这个时候,文件中的中文会以乱码形式出现,将其设置为False,中文字符显示正确
data = json.dump(param,f,ensure_ascii=False)
读取json文件
import json
'''1.导包,2.调用dump(内容,文件名称及路径)/load()
注意:写入用w,读取用r
'''
#读取操作
#打开文件
with open('../case/data2.json',encoding='utf-8')as f:
data=json.load(f)
print(data)
5.案例
网站:http://cal.apple886.com/
对网页计算器,进行加法的测试操作,通过读取数据文件中的数据来执行用例
实现步骤:
1.采用po模式的分层思想对页面进行封装
2,编写测试脚本
3.使用参数化传入测试数据
4.把测试数据定义到JSON数据文件中
1.1.Base模板 框架模块
#功能类
"""
计算器操作
加法分析:
1.查找元素
2.对0-9进行点击操作
3.点击等于操作
4.断言,获取结果 获取value属性进行封装
5.截图
"""
class Base:
#初始化方法
def __init__(self,driver):
self.driver=driver
#查找元素
def base_find_element(self):
pass
#点击
def base_click_result(self):
pass
#获取value属性方法封装
def base_get_value(self):
pass
#截图
def base_get_img(self):
pass
获取driver
from selenium import webdriver
from po1 import page
class GetDriver:
# 设置类属性
driver = None
# 获取driver
@classmethod
def get_driver(cls):
if cls.driver is None:
# 实例化浏览器 最大化
cls.driver = webdriver.Chrome().maximize_window()
# 打开浏览器
cls.driver.get(page.url)
return cls.driver
# 退出driver
@classmethod
def quit_dirver(cls):
if cls.driver:
cls.driver.quit()
# 注意:此处有大坑
cls.driver = None
if __name__ == "__main__":
# 第一次
print(GetDriver().get_driver())
# 第二次
print(GetDriver().get_driver())
1.2.page模板 框架模块
init:
'''
以下为服务器域名配置地址
'''
url="http://localhost"
'''
以下为计算器配置数据
'''
'''
获取元素的属性值进行定位,具体项目具体操作定位元素即可
如果前端页面的元素属性有所改动,只需修改该页面的属性值即可
'''
# 说明:由于数字键有一定的规律,所以暂时不使用定位此键,用到的时候在考虑此键怎么解决
# num = "123456789" #字符串
# for n in num:
# clac_num = By.CSS_SELECTOR, "simple{}".format(n)
# 加号运算
clac_add = By.CSS_SELECTOR, "#simpleAdd"
# 等号
clac_eq = By.CSS_SELECTOR, "#simpleEqual"
# 获取结果
clac_result = By.CSS_SELECTOR, "#resultIpt"
# 点击清屏
clac_clear = By.CSS_SELECTOR, "#simpleClearAllBtn"
page_add:
from po1.base.base import Base
class PageAdd(Base):
#点击数字方法
def page_click_sum(self):
pass
#点击加法
def page_click_add(self):
pass
#点击等于
def page_click_equal(self):
pass
#获取结果
def page_get_result(self):
pass
#点击清屏
def page_click_clear(self):
pass
#组装加法业务方法
def page_add(self):
pass
1.3.scripts模板 框架模块
import unittest
import po1.page import page
class TestAdd(unittest.TestCase):
#setUpclass
@classmethod
def setUpClass(cls):
#初始化 计算页面对象
pass
#tearDownclass
@classmethod
def dearDownClass(self):
#关闭driver
pass
#测试加法
def test_add(self):
#调用计算的方法
#断言
#截图
pass
2.1.base功能实战:
# 功能类
"""
计算器操作
加法分析:
1.查找元素
2.对0-9进行点击操作
3.点击等于操作
4.断言,获取结果 获取value属性进行封装
5.截图
"""
from selenium.webdriver.support.wait import WebDriverWait
class Base:
# 初始化方法
def __init__(self, driver):
self.driver = driver
# 查找元素
def base_find_element(self, loc, timeout=30, pull=0.5):
"""
#该注释出现的方法:""""""并点击回车按钮即可(注意必须在函数下面进行该操作)
:param loc: 元素的配置信息,格式为元组
:param timeout: 默认超时时间,30m,可以修改
:param pull: 访问频率,默认0.5,可修改
:return: 返回查找到的元素
"""
# 显示等待
return WebDriverWait(self.driver,
timeout=timeout,
poll_frequency=pull).until(lambda x: x.finf.element(*loc))
# 点击
def base_click_result(self,loc):
#调用查找元素,并进行点击
self.base_find_element(loc).click()
# 获取value属性方法封装
def base_get_value(self,loc,value):
#使用get_attribute()方法获取指定元素的属性值
#注意:返回
return self.base_find_element(loc).get_attribute("value")
# 截图
def base_get_img(self):
self.driver.get_screenshot_as_file("../image/po1_1.jpg")
获取driver
from selenium import webdriver
from po1 import page
class GetDriver:
# 设置类属性
driver = None
# 获取driver
@classmethod
def get_driver(cls):
if cls.driver is None:
# 实例化浏览器 最大化
cls.driver = webdriver.Chrome().maximize_window()
# 打开浏览器
cls.driver.get(page.url)
return cls.driver
# 退出driver
@classmethod
def quit_dirver(cls):
if cls.driver:
cls.driver.quit()
# 注意:此处有大坑
cls.driver = None
if __name__ == "__main__":
# 第一次
print(GetDriver().get_driver())
# 第二次
print(GetDriver().get_driver())
2.2 page业务实战
init
'''
以下为服务器域名配置地址
'''
url="http://localhost"
'''
以下为计算器配置数据
'''
'''
获取元素的属性值进行定位,具体项目具体操作定位元素即可
如果前端页面的元素属性有所改动,只需修改该页面的属性值即可
'''
# 说明:由于数字键有一定的规律,所以暂时不使用定位此键,用到的时候在考虑此键怎么解决
# num = "123456789" #字符串
# for n in num:
# clac_num = By.CSS_SELECTOR, "simple{}".format(n)
# 加号运算
clac_add = By.CSS_SELECTOR, "#simpleAdd"
# 等号
clac_eq = By.CSS_SELECTOR, "#simpleEqual"
# 获取结果
clac_result = By.CSS_SELECTOR, "#resultIpt"
# 点击清屏
clac_clear = By.CSS_SELECTOR, "#simpleClearAllBtn"
page_add:
from selenium.webdriver.common.by import By
from po1.base.base import Base
from po1 import page
'''
业务逻辑:数字---加号---数字-----等于----获取结果----清空
'''
class PageAdd(Base):
# 点击数字方法
def page_click_num(self, num):
for n in num:
# 拆开单个按钮的定位方式
loc = By.CSS_SELECTOR, "simple{}".format(n)
self.base_find_element(loc)
# 点击加法
def page_click_add(self):
self.base_find_element(page.clac_add)
# 点击等于
def page_click_equal(self):
self.base_find_element(page.clac_eq)
# 获取结果
def page_get_result(self):
self.base_find_element(page.clac_result)
# 点击清屏
def page_click_clear(self):
self.base_find_element(page.clac_clear)
# 组装加法业务方法
def page_add(self,a,b):
self.page_click_num(a)
self.page_click_add()
self.page_click_num(b)
self.page_click_equal()
self.page_get_result()
self.page_click_clear()
2.3.scripts模块实战
import unittest
from parameterized import parameterized
from po1.base.get_driver import GetDriver
from po1.page.page_add import PageAdd
def get_data():
data = read_json("calc.json")
# 新建空列表
arrs = []
for d in data.values():
arrs.append((d["a"], d["b"], d["expect"]))
return arrs
class TestAdd(unittest.TestCase):
driver=None
#setUpclass
@classmethod
def setUpClass(cls):
#获取driver
cls.driver=GetDriver.get_driver()
#初始化 计算页面对象
cls.calc=PageAdd(cls.driver)
#tearDownclass
@classmethod
def dearDownClass(cls):
#关闭driver
GetDriver().quit_dirver()
#测试加法
@parameterized.expand(get_data())
def test_add(self,a,b,expect):
#调用计算的方法
self.calc.page_add(a,b)
print("预期结果",expect,"实际结果",self.calc.page_get_result())
try:
#断言
self.assertEqual(self.calc.page_get_result(),str(expect))
except:
# 截图
self.calc.page_get_img()
构造数据:使用json方法
#file文件
{
"calc_001":{
"a": 1,
"b": 2,
"expect": 3
},
"calc_002":{
"a": 99,
"b": 2,
"expect": 101
},
"calc_003":{
"a": 10000,
"b": 2,
"expect": 10002
}
}