接口自动化——参数化

之前有说过,通过pytest测试框架标记参数化功能可以实现数据驱动测试。数据驱动测试使用的文件主要有以下类型:

  • txt 文件
  • csv 文件
  • excel 文件
  • json 文件
  • yaml 文件
  • ....

本文主要讲的就是以上几种文件类型的读取和使用

一.txt 文件读取使用

首先创建一个 txt 文件,文件内容为:

张三,男,2024-09-10

李四,女,2022-09-10

王五,男,2090-09-10

然后读取文件内容

python 复制代码
def get_txt_data():
    with open(r"D:\python_project\API_Auto\API3\data\txt_data", encoding="utf-8") as file:
        content = file.readlines()
        # print(content)

        # 去掉数据后面的换行符
        list_data = []
        list_data1 = []
        for i in content:
            list_data.append(i.strip())

        # 将数据分割
        for i in list_data:
            list_data1.append(i.split(","))

    return list_data1

这样就得到了 符合参数化要求的参数,对读取的内容进行使用:

python 复制代码
@pytest.mark.parametrize(
    ("name", "gender", "data"), get_txt_data())
def test_txt_func(name, gender, data):
    print(f'输入名字:{name}')
    print(f'输入性别 :{gender}')
    print(f'输入日期:{data}')

输出为:

python 复制代码
D:\python_project\API_Auto\API3\venv\Scripts\python.exe D:\python_project\API_Auto\API3\main.py 
============================= test session starts =============================
platform win32 -- Python 3.10.6, pytest-8.3.5, pluggy-1.5.0 -- D:\python_project\API_Auto\API3\venv\Scripts\python.exe
cachedir: .pytest_cache
rootdir: D:\python_project\API_Auto\API3
configfile: pytest.ini
plugins: allure-pytest-2.13.5, result-log-1.2.2
collecting ... [['张三', 18.0, 185.0, 10000000.0], ['李四', 30.0, 178.0, 2000.0], ['王五', 40.0, 169.0, 43323.0]]
collected 3 items

testcases/test_ddt.py::test_txt_func[张三-男-2024-09-10] 输入名字:张三
输入性别 :男
输入日期:2024-09-10
PASSED
testcases/test_ddt.py::test_txt_func[李四-女-2022-09-10] 输入名字:李四
输入性别 :女
输入日期:2022-09-10
PASSED
testcases/test_ddt.py::test_txt_func[王五-男-2090-09-10] 输入名字:王五
输入性别 :男
输入日期:2090-09-10
PASSED

============================== 3 passed in 0.06s ==============================
Report successfully generated to .\report

Process finished with exit code 0

二.csv 文件读取使用

首先创建一个csv文件,内容为:

复制代码
1,2,3
1,3,3
2,2,4

然后读取文件内容

python 复制代码
import csv


def get_csv_data():
    list1 = []
    f = csv.reader(open(r"D:\python_project\API_Auto\API3\data\x_y_z.csv", encoding="utf-8"))
    for i in f:
        # list1.append(i.strip())
        
        # [int(element) for element in i],  列表推导式,它的作用是对 i 中的每个元素进行遍历,并将每个元素从字符串(str)转换为整数(int)
        a = [int(element) for element in i]
        list1.append(a)

    return list1

然后使用读取到的数据

python 复制代码
@pytest.mark.parametrize(
    ("x", "y", "z"), get_csv_data()
)
def test_csv_func(x, y, z):
    assert x * y == z

输出为:

python 复制代码
D:\python_project\API_Auto\API3\venv\Scripts\python.exe D:\python_project\API_Auto\API3\main.py 
============================= test session starts =============================
platform win32 -- Python 3.10.6, pytest-8.3.5, pluggy-1.5.0 -- D:\python_project\API_Auto\API3\venv\Scripts\python.exe
cachedir: .pytest_cache
rootdir: D:\python_project\API_Auto\API3
configfile: pytest.ini
plugins: allure-pytest-2.13.5, result-log-1.2.2
collecting ... [['张三', 18.0, 185.0, 10000000.0], ['李四', 30.0, 178.0, 2000.0], ['王五', 40.0, 169.0, 43323.0]]
collected 3 items

testcases/test_ddt.py::test_csv_func[1-2-3] FAILED
testcases/test_ddt.py::test_csv_func[1-3-3] PASSED
testcases/test_ddt.py::test_csv_func[2-2-4] PASSED

================================== FAILURES ===================================
____________________________ test_csv_func[1-2-3] _____________________________

x = 1, y = 2, z = 3

    @pytest.mark.parametrize(
        ("x", "y", "z"), get_csv_data()
    )
    def test_csv_func(x, y, z):
>       assert x * y == z
E       assert (1 * 2) == 3

testcases\test_ddt.py:21: AssertionError
----------------------------- Captured log setup ------------------------------
WARNING  pytest_result_log:plugin.py:122 ---------------Start: testcases/test_ddt.py::test_csv_func[1-2-3]---------------
---------------------------- Captured log teardown ----------------------------
WARNING  pytest_result_log:plugin.py:128 ----------------End: testcases/test_ddt.py::test_csv_func[1-2-3]----------------
=========================== short test summary info ===========================
FAILED testcases/test_ddt.py::test_csv_func[1-2-3] - assert (1 * 2) == 3
========================= 1 failed, 2 passed in 0.13s =========================
Report successfully generated to .\report

Process finished with exit code 0

三.excel 文件读取使用

首先创建一个excel文件,文件内容为:

然后在读取Excel数据内容前,要针对不同版本使用不同的第三方库

  • xls
    • office 2003版本
      • 安装:xlrd第三库
      • 必须指定版本
      • pip install xlrd==1.2.0
  • xlsx
    • office 2016版本
      • 安装:openpyxl第三方库
      • 默认安装最新的版本库即可
      • pip install openpyxl

安装完后,读取 数据:

python 复制代码
import xlrd


# # 读取excel 文件数据获取xls文件对象
# xls = xlrd.open_workbook(r'D:\python_project\API_Auto\API3\data\test.xlsx')
#
# # 获取excel 中的sheet 表,0代表第一张 表的索引、
# sheet = xls.sheet_by_index(0)
#
# # 输出数据列
# print(sheet.ncols)
#
# # 输出数据行
# print(sheet.nrows)
#
# # 读取具体某一行内容,0代表第一行数据索引
# print(sheet.row_values(1))
#

def get_excel_data(path):

    list_excel =  []
    xls = xlrd.open_workbook(path)

    # 获取excel 中的sheet 表,0代表第一张 表的索引、
    sheet = xls.sheet_by_index(0)

    for i in range(sheet.nrows):
        list_excel.append(sheet.row_values(i))

    # 删除表头数据
    list_excel.pop(0)

    # print(list_excel)
    return list_excel

使用读取到的数据:

python 复制代码
@pytest.mark.parametrize(
    ("name", "age", "height", "money"), get_excel_data(r"D:\python_project\API_Auto\API3\data\test.xlsx")
)
def test_excel_func(name, age, height, money):
    print(f"name是{name},age是{age},height是{height},money是{money}")

输出结果为 :

python 复制代码
D:\python_project\API_Auto\API3\venv\Scripts\python.exe D:\python_project\API_Auto\API3\main.py 
============================= test session starts =============================
platform win32 -- Python 3.10.6, pytest-8.3.5, pluggy-1.5.0 -- D:\python_project\API_Auto\API3\venv\Scripts\python.exe
cachedir: .pytest_cache
rootdir: D:\python_project\API_Auto\API3
configfile: pytest.ini
plugins: allure-pytest-2.13.5, result-log-1.2.2
collecting ... collected 3 items

testcases/test_ddt.py::test_excel_func[张三-18.0-185.0-10000000.0] name是张三,age是18.0,height是185.0,money是10000000.0
PASSED
testcases/test_ddt.py::test_excel_func[李四-30.0-178.0-2000.0] name是李四,age是30.0,height是178.0,money是2000.0
PASSED
testcases/test_ddt.py::test_excel_func[王五-40.0-169.0-43323.0] name是王五,age是40.0,height是169.0,money是43323.0
PASSED

============================== 3 passed in 0.09s ==============================
Report successfully generated to .\report

Process finished with exit code 0

四.json 文件的读取使用

首先创建一个json文件,内容为:

复制代码
[
  [1,2,3],
  [4,2,6],
  [7,8,9]
]

然后读取文件内容

python 复制代码
def get_json_data(path):
    with open(path, encoding="utf-8") as file:
        content = file.read()

    # print(eval(content))
    # print(type(eval(content)))

    # eval() : 去掉最外层的引号
    return eval(content)

对读取到的内容进行使用:

python 复制代码
@pytest.mark.parametrize(
    ("x", "y", "z"), get_json_data(r'D:\python_project\API_Auto\API3\data\json.json')
)
def test_json_func(x, y, z):
    assert x + y == z

输出结果为:

python 复制代码
D:\python_project\API_Auto\API3\venv\Scripts\python.exe D:\python_project\API_Auto\API3\main.py 
============================= test session starts =============================
platform win32 -- Python 3.10.6, pytest-8.3.5, pluggy-1.5.0 -- D:\python_project\API_Auto\API3\venv\Scripts\python.exe
cachedir: .pytest_cache
rootdir: D:\python_project\API_Auto\API3
configfile: pytest.ini
plugins: allure-pytest-2.13.5, result-log-1.2.2
collecting ... collected 3 items

testcases/test_ddt.py::test_json_func[1-2-3] PASSED
testcases/test_ddt.py::test_json_func[4-2-6] PASSED
testcases/test_ddt.py::test_json_func[7-8-9] FAILED

================================== FAILURES ===================================
____________________________ test_json_func[7-8-9] ____________________________

x = 7, y = 8, z = 9

    @pytest.mark.parametrize(
        ("x", "y", "z"), get_json_data(r'D:\python_project\API_Auto\API3\data\json.json')
    )
    def test_json_func(x, y, z):
>       assert x + y == z
E       assert (7 + 8) == 9

testcases\test_ddt.py:35: AssertionError
----------------------------- Captured log setup ------------------------------
WARNING  pytest_result_log:plugin.py:122 --------------Start: testcases/test_ddt.py::test_json_func[7-8-9]---------------
---------------------------- Captured log teardown ----------------------------
WARNING  pytest_result_log:plugin.py:128 ---------------End: testcases/test_ddt.py::test_json_func[7-8-9]----------------
=========================== short test summary info ===========================
FAILED testcases/test_ddt.py::test_json_func[7-8-9] - assert (7 + 8) == 9
========================= 1 failed, 2 passed in 0.14s =========================
Report successfully generated to .\report

Process finished with exit code 0

五.yaml 文件读取使用

1.yaml数据读写

序列化:内存中数据,转化为文件

反序列化:将文件转化为内存数据 需要操作yaml文件,安装第三方库

pip install pyyaml

2.序列化 将yaml 数据写入文件中

python 复制代码
"""
YAML 是一个可读性 高,用来达标数据序列化的格式

基本语法格式:
    1.区分大小写
    2.使用缩进表示层级 关系
    3.缩进不能 使用 tab  建,只能使用空格
    4.缩进的空格数不重要,只要相同 层级的元素左对齐即可
    5.可以使用 注释符号 #

yaml  序列化 常用数据类型:
    1.对象(python中的 字段,键值对)
    2.数组(python 中的列表 )
    3.纯量:单个的、不可再分值
    4.布尔值
    5.空值

YAML 数据读写:
    序列化:将内存 中数据转化为文件
    反序列化 :将文件转化为内存数据

需要安装第三方库:pip install pyyaml
"""

data = {
    '数字': [1, 2, 3, 4, -1],
    '字符串': ["a", "@#", "c"],
    '空值': None,
    '布尔值': [True, False],
    '元组': (1, 2, 3)
}

import yaml

# 将 python 数据类型,转换为yaml 格式
yaml_data = yaml.safe_dump(
    data,  # 要转化的数据内容
    allow_unicode=True,  # 允许unicode 字符,中文原样显示
    sort_keys=False  # 不进行排序,原样输出
)

# 序列化  将yaml 数据写入文件中
f = open(r"D:\python_project\API_Auto\API3\data\yaml.yaml", "w", encoding="utf-8")
f.write(yaml_data)
f.close()

3.反序列化 读取yaml 文件中的数据

python 复制代码
# 反序列化   读取yaml 文件中的数据
f = open(r"D:\python_project\API_Auto\API3\data\yaml.yaml", "r", encoding="utf-8")
s = f.read()
data_yaml = yaml.safe_load(s)
print(data_yaml)

4.写入一个大列表里面嵌套小列表

python 复制代码
# 写入一个大列表里面嵌套小列表

list1 = [['张三', 18.0, 185.0, 10000000.0], ['李四', 30.0, 178.0, 2000.0], ['王五', 40.0, 169.0, 43323.0]]

yaml_data = yaml.safe_dump(
    list1,  # 要转化的数据内容
    allow_unicode=True,  # 允许unicode 字符,中文原样显示
    sort_keys=False  # 不进行排序,原样输出
)

# 序列化  将yaml 数据写入文件中
f = open(r"D:\python_project\API_Auto\API3\data\yaml1.yaml", "w", encoding="utf-8")
f.write(yaml_data)
f.close()

完整代码为:

python 复制代码
data = {
    '数字': [1, 2, 3, 4, -1],
    '字符串': ["a", "@#", "c"],
    '空值': None,
    '布尔值': [True, False],
    '元组': (1, 2, 3)
}

import yaml


def get_yaml_data():
    # 将 python 数据类型,转换为yaml 格式
    yaml_data = yaml.safe_dump(
        data,  # 要转化的数据内容
        allow_unicode=True,  # 允许unicode 字符,中文原样显示
        sort_keys=False  # 不进行排序,原样输出
    )

    # 序列化  将yaml 数据写入文件中
    f = open(r"D:\python_project\API_Auto\API3\data\yaml.yaml", "w", encoding="utf-8")
    f.write(yaml_data)
    f.close()

    # 反序列化   读取yaml 文件中的数据
    f = open(r"D:\python_project\API_Auto\API3\data\yaml.yaml", "r", encoding="utf-8")
    s = f.read()
    data_yaml = yaml.safe_load(s)
    print(data_yaml)

    # 写入一个大列表里面嵌套小列表

    list1 = [['张三', 18.0, 185.0, 10000000.0], ['李四', 30.0, 178.0, 2000.0], ['王五', 40.0, 169.0, 43323.0]]

    yaml_data = yaml.safe_dump(
        list1,  # 要转化的数据内容
        allow_unicode=True,  # 允许unicode 字符,中文原样显示
        sort_keys=False  # 不进行排序,原样输出
    )

    # 序列化  将yaml 数据写入文件中
    f = open(r"D:\python_project\API_Auto\API3\data\yaml1.yaml", "w", encoding="utf-8")
    f.write(yaml_data)
    f.close()

    # 反序列化   读取yaml 文件中的数据
    f = open(r"D:\python_project\API_Auto\API3\data\yaml1.yaml", "r", encoding="utf-8")
    s = f.read()
    data_yaml1 = yaml.safe_load(s)
    print(data_yaml1)

    return data_yaml1

使用读取到的数据:

python 复制代码
@pytest.mark.parametrize(
    ("x"), get_yaml_data()
)
def test_yaml_func(x):
    for i in x:
        print(i)

输出为 :

python 复制代码
D:\python_project\API_Auto\API3\venv\Scripts\python.exe D:\python_project\API_Auto\API3\main.py 
============================= test session starts =============================
platform win32 -- Python 3.10.6, pytest-8.3.5, pluggy-1.5.0 -- D:\python_project\API_Auto\API3\venv\Scripts\python.exe
cachedir: .pytest_cache
rootdir: D:\python_project\API_Auto\API3
configfile: pytest.ini
plugins: allure-pytest-2.13.5, result-log-1.2.2
collecting ... {'数字': [1, 2, 3, 4, -1], '字符串': ['a', '@#', 'c'], '空值': None, '布尔值': [True, False], '元组': [1, 2, 3]}
[['张三', 18.0, 185.0, 10000000.0], ['李四', 30.0, 178.0, 2000.0], ['王五', 40.0, 169.0, 43323.0]]
collected 3 items

testcases/test_ddt.py::test_yaml_func[x0] 张三
18.0
185.0
10000000.0
PASSED
testcases/test_ddt.py::test_yaml_func[x1] 李四
30.0
178.0
2000.0
PASSED
testcases/test_ddt.py::test_yaml_func[x2] 王五
40.0
169.0
43323.0
PASSED

============================== 3 passed in 0.10s ==============================
Report successfully generated to .\report

Process finished with exit code 0
相关推荐
chao_7893 分钟前
二分查找篇——寻找旋转排序数组中的最小值【LeetCode】
python·线性代数·算法·leetcode·矩阵
金玉满堂@bj20 分钟前
PyCharm 中 Python 解释器的添加选项及作用
ide·python·pycharm
程序员三藏25 分钟前
如何使用Pytest进行测试?
自动化测试·软件测试·python·测试工具·职场和发展·测试用例·pytest
随心点儿1 小时前
使用python 将多个docx文件合并为一个word
开发语言·python·多个word合并为一个
不学无术の码农1 小时前
《Effective Python》第十三章 测试与调试——使用 Mock 测试具有复杂依赖的代码
开发语言·python
sleepybear11131 小时前
在Ubuntu上从零开始编译并运行Home Assistant源码并集成HACS与小米开源的Ha Xiaomi Home
python·智能家居·小米·home assistant·米家·ha xiaomi home
纪伊路上盛名在1 小时前
(鱼书)深度学习入门1:python入门
人工智能·python·深度学习
夏末蝉未鸣012 小时前
python transformers笔记(TrainingArguments类)
python·自然语言处理·transformer
德育处主任Pro2 小时前
「py数据分析」04如何将 Python 爬取的数据保存为 CSV 文件
数据库·python·数据分析
咸鱼鲸2 小时前
【PyTorch】PyTorch中数据准备工作(AI生成)
人工智能·pytorch·python