什么是数据驱动
- 数据驱动就是数据的改变从而驱动自动化测试的执行,最终引起测试结果的改变。简单来说,就是参数化的应用。数据量小的测试用例可以使用代码的参数化来实现数据驱动,数据量大的情况下建议大家使用一种结构化的文件(例如 yaml,json, 等)来对数据进行存储,然后在测试用例中读取这些数据。
-
应用:
- App、Web、接口自动化测试
- 测试步骤的数据驱动
- 测试数据的数据驱动
- 配置的数据驱动
1 pytest结合数据驱动-yaml
1.1 yaml文件介绍
YAML(全称为"YAML Ain't Markup Language")是一种人类可读的数据序列化格式,它具有简洁、易读、易写的特点。YAML适用于配置文件、数据传输和表示复杂数据结构等场景。
以下是一些关键特点和用法示例:
- 简洁易读:YAML使用缩进和空白行来组织数据,以使结构清晰可读
- 键值对:使用冒号(:)来表示键值对关系
#示例1
name: jardon
age: 18
相当于字典{'name':'jardon','age':18}
- 数组:使用短横线(-)来表示一组相同类型的值。
#示例2
language:
- python
- java
- go
相当于{'language':['python','java','go']}
- 嵌套数据结构:可以使用缩进来表示嵌套关系
person:
name: jardon
age: 18
address:
city: 深圳
country: 中国
- 注释:以井号(#)开头的行表示注释
#这是一条注释
name: jardon #这是姓名字段
- 多行文本:通过使用管道符(|)或大于号(>)来表示多行文本
description: |
这是一个示例文件,
包含了一些注释。
multiline_description: >
这是一个示例文件,
包含了一些注释。
1.2 yaml文件的使用
- Python读取yaml文件需要安装pyyaml第三方库,通过pip install pyyaml
或者settings-->project-->python interpreter进行安装
- 读取文件方式
import yaml
file_path = './my.yaml' #文件路径
#打开文件
with open(file_path, 'r', encoding='utf-8') as f:
#读取文件的数据
data = yaml.safe_load(f)
- 工程目录结构
data 目录:存放 yaml 数据文件
func 目录:存放被测函数文件
testcase 目录:存放测试用例文件
- 测试准备
被测对象:operation.py
;测试用例:test_add.py
;测试数据:data.yaml
# operation.py 文件内容
def my_add(x, y):
result = x + y
return result
# test_add.py 文件内容
#读取yaml中的数据
def get_yaml():
"""
获取json数据
:return: 返回数据的结构:[[1, 1, 2], [3, 6, 9], [100, 200, 300]]
"""
with open('../datas/data.yaml', 'r') as f:
data = yaml.safe_load(f)
return data
class TestWithYaml:
@pytest.mark.parametrize('x,y,expected', get_yaml())
def test_add(self, x, y, expected):
assert my_add(int(x), int(y)) == int(expected)
# data.yaml 文件内容
-
- 1
- 1
- 2
-
- 3
- 6
- 9
-
- 100
- 200
- 300
2 pytest结合数据驱动-excel
2.1 openpyxl 库的安装
openpyxl库的安装跟pyyaml库的安装一样,方法一通过在Terminal界面,执行pip install openpyxl,如下,我的是已经安装过了
第二个方式在settings-->project-->python interpreter进行安装
2.2 openpyxl 库的操作
openpyxl操作Excel工作薄、工作表和单元格方式如下
import openpyxl
# 获取工作簿
book = openpyxl.load_workbook('../data/params.xlsx')
# 读取工作表
sheet = book.active
# 读取单个单元格
cell_a1 = sheet['A1']
cell_a3 = sheet.cell(column=1, row=3) # A3
# 读取多个连续单元格
cells = sheet["A1":"C3"]
# 获取单元格的值
cell_a1.value
params.xlsx文件内容如下
2.3 Pytest 数据驱动结合 Excel 文件
Excel数据驱动的工程目录跟yaml工程目录一致,实现pytest+excel数据驱动代码如下
# operation.py 文件内容
def my_add(x, y):
result = x + y
return result
# test_add.py 文件内容
import openpyxl
import pytest
# 读取Excel文件
def get_excel():
# 获取工作簿
book = openpyxl.load_workbook('../data/params.xlsx')
# 获取活动行(非空白的)
sheet = book.active
# 提取数据,格式:[[1, 2, 3], [3, 6, 9], [100, 200, 300]]
values = []
for row in sheet:
line = []
for cell in row:
line.append(cell.value)
values.append(line)
return values
#测试用例
class TestWithEXCEL:
@pytest.mark.parametrize('x,y,expected', get_excel())
def test_add(self, x, y, expected):
assert my_add(int(x), int(y)) == int(expected)
3 pytest结合数据驱动-csv
3.1 csv 文件使用
-
读取数据
- 内置函数:
open()
- 内置模块:
csv
- 内置函数:
-
方法:
csv.reader(iterable)
- 参数:iterable ,文件或列表对象
- 返回:迭代器,每次迭代会返回一行数据。
# 读取csv文件内容
def get_csv():
with open('demo.csv', 'r') as file:
raw = csv.reader(file)
for line in raw:
print(line)
3.2 Pytest 数据驱动结合 csv 文件
# operation.py 文件内容
def my_add(x, y):
result = x + y
return result
# test_add.py 文件内容
# 读取 data目录下的 params.csv 文件
import csv
def get_csv():
"""
获取csv数据
:return: 返回数据的结构:[[1, 1, 2], [3, 6, 9], [100, 200, 300]]
"""
with open('../data/params.csv', 'r') as file:
raw = csv.reader(file)
data = []
for line in raw:
data.append(line)
return data
#测试用例
class TestWithCSV:
@pytest.mark.parametrize('x,y,expected', get_csv())
def test_add(self, x, y, expected):
assert my_add(int(x), int(y)) == int(expected)
# params.csv 文件内容
1,1,2
3,6,9
100,200,300
4 pytest结合数据驱动-json
4.1 json 文件使用
- 查看 json 文件
- pycharm
- txt 记事本
- 读取 json 文件
- 内置函数 open()
- 内置库 json
- 方法:
json.loads()
- 方法:
json.dumps()
# 读取json文件内容
def get_json():
with open('demo.json', 'r') as f:
data = json.loads(f.read())
print(data)
4.2 Pytest 数据驱动结合 json 文件
# operation.py 文件内容
def my_add(x, y):
result = x + y
return result
# test_add.py 文件内容
# 读取json文件
def get_json():
"""
获取json数据
:return: 返回数据的结构:[[1, 1, 2], [3, 6, 9], [100, 200, 300]]
"""
with open('../data/params.json', 'r') as f:
data = json.loads(f.read())
return list(data.values())
#测试用例
class TestWithJSON:
@pytest.mark.parametrize('x,y,expected',get_json())
def test_add(self, x, y, expected):
assert my_add(int(x), int(y)) == int(expected)
# params.json 文件内容
{
"case1": [1, 1, 2],
"case2": [3, 6, 9],
"case3": [100, 200, 300]
}