接口自动化——参数化

之前有说过,通过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
相关推荐
买了一束花4 分钟前
二、机器学习中Python变量基础
开发语言·python·机器学习·conda
Gui林21 分钟前
ros2 humble 控制真实机械臂(以lerobot为例)
linux·python
钢铁男儿1 小时前
Python基本语法(函数partial)
前端·javascript·python
满怀10151 小时前
【Robocorp实战指南】Python驱动的开源RPA框架
python·开源·rpa
bj32811 小时前
树的同构问题--Python
开发语言·python·算法
橙色小博2 小时前
HTTPS协议:更安全的HTTP
网络·python·网络协议·安全·http·https
小龙在山东2 小时前
flask 获取各种请求数据:GET form-data x-www-form-urlencoded JSON headers 上传文件
python·flask·json
纪元A梦2 小时前
华为OD机试真题——告警抑制(2025A卷:100分)Java/python/JavaScript/C/C++/GO最佳实现
java·c语言·javascript·c++·python·华为od
程序媛学姐3 小时前
Spring Boot的GraalVM支持:构建低资源消耗微服务
spring boot·python·微服务