接口测试常用文件读写
- ⾸先为什么要封装⽂件读写的⽅法,原因有如下⼏点:
- 读接⼝配置:⽐如我们接⼝的⼀些配置信息(域名、接⼝路径、账号)等我们⼀般都是放在config.yaml⽂件⾥,我们需要先读取到配置,后续拼接成接⼝的请求信息
- 读数据库配置:⽐如我们的数据库信息⼀般是放在db.ini⽂件中,我们需要先读取到配置,后续可以根据配置信息连接数据库进⾏取数据或者数据库字段断⾔
- 读写测试数据:⽐如我们的本次的接⼝测试数据是写在api.yaml⾥的,我们需要先读取数据,⽣成测试⽤例,有时候我们的api.yaml还有⼀些动态的模板参数需要替换,这个时候我们就需要写⼊⽂件了
- 读⽇志⽂件:⽐如有时候我们⽇志⾥记录了接⼝报错信息,我们需要分类读取出来,放到测试报告中或者群消息通知中来做错误告警
YAML/yml 文件(.yaml/.yml)
- 参考链接认识接口自动化封装中的YAML用例
- 参考链接YAML教程-1-基础入门
- 基本语法
- 大小写敏感性:YAML区分大小写,因此关键字和值的大小写必须一致。
缩进表示层级:数据的层级结构通过缩进来表示,每个缩进级别通常对应一个列表项或字典的键值对。 空格缩进:缩进必须使用空格,不能使用tab字符,以确保跨平台的一致性。
对齐的灵活性:尽管具体的空格数量没有严格规定,但为了代码的可读性和一致性,建议保持同一层级的元素具有相同的缩进空格数,实现视觉上的对齐。- 注释符号:以#开头的字符直到行尾都被视为注释,不会被YAML解析,这样可以在文档中添加说明和备注。
- 大小写敏感性:YAML区分大小写,因此关键字和值的大小写必须一致。
if file_extension == '.yaml' or file_extension == '.yml': # 读取YAML文件,返回字典
with open(path,'r',encoding='UTF-8') as fp:
# 返回数据类型是dict
return yaml.safe_load(fp)
if file_extension == '.yaml' or file_extension == '.yml': # 读取YAML文件,返回字典
with open(path,'r',encoding='UTF-8') as fp:
# 返回数据类型是dict
yaml.dump(data,fp,default_flow_style=False) # default_flow_style=False:生成 “块状” YAML(更易读),而非紧凑的 “流式” 格式。
原理:
- YAML 文件是键值对或嵌套结构(类似字典 / 列表),yaml.safe_load会将其解析为 Python 原生数据结构(字典、列表等)。
- 用safe_load而非load:load可能执行 YAML 中的代码(有安全风险),safe_load仅解析数据,更安全。
- allow_unicode=True:确保中文正常写入(不转为 Unicode 编码);
- default_flow_style=False:生成 “块状” YAML(更易读),而非紧凑的 “流式” 格式。
INI/conf 配置文件(.ini/.conf)
核心逻辑:通过ConfigParser构建配置结构,再写入文件。
步骤解析:
- 初始化ConfigParser对象;
- 遍历输入数据data(需为嵌套字典,格式:{section: {key: value, …}, …}),将每个section和对应的options添加到配置对象;
- 用config.write(fp)将配置写入文件,自动生成 INI 格式(带[section]和key=value)。
- INI 语法速览(就 4 条)
- 分节 [section]
节名大小写无关,首尾空格自动去掉。 - 键值对 key = value 或 key:value
等号/冒号都可,左右空格会自动剥离。 - 注释
行首 # 或 ; 整行注释,暂无行尾注释标准。 - 重复项
同一节内 key 重复,后者覆盖前者;不同节互不干扰。
- 分节 [section]
- ini文件的格式数据
[database]
host = 127.0.0.1
port = 3306
username = root
password = 123456
charset = utf8mb4
dbname = testdb
[pool]
min_size = 5
max_size = 20
timeout = 10
elif file_extension in ('.ini','.conf'):
config = ConfigParser()
with open(path,'r',encoding='UTF-8') as fp:
config.read_file(fp) # read_file读取的是流 fp
return config
elif file_extension in ('.ini','.conf'):
config = ConfigParser()
for section ,options in data.items():
config[section] = dict(options)
with open(path,'w',encoding='utf-8') as fp:
config.write(fp)
- ConfigParser 提供三种加载方式:
| 方法 | 输入 | 场景 |
|---|---|---|
read(filenames, encoding=None) | 文件路径(可列表) | 最常用,自动打开、关闭文件 |
read_file(fp, filename=None) | 已打开的文件对象 | 文件已在外部打开,手动控制编码/模式 |
read_string(string) | 字符串 | 测试/远端下载内容直接解析 |
read_dict(dictionary) | 嵌套 dict | 程序构造配置 |
CSV 文件(.csv)
核心逻辑:用pandas将数据转为DataFrame,再写入 CSV。
关键代码:pd.DataFrame(data).to_csv(…)
- 要求data为可转为表格的结构(如列表套字典、二维列表等);
- index=False:禁止写入 DataFrame 的索引列(避免多余的行号);
- encoding=‘utf-8’:确保中文不乱码。
elif file_extension == '.csv':
return pd.read_csv(path).
elif file_extension == '.csv':
pd.DataFrame(data).to_csv(path,index=False,encoding='utf-8')
Excel 文件(.xlsx)
处理模块:pandas(依赖openpyxl引擎)
核心代码:pd.read_excel(path, engine=‘openpyxl’)
原理:
- pandas本身不直接支持.xlsx格式,需依赖openpyxl作为引擎(处理 Excel 2007 + 格式)。
- read_excel会将 Excel 工作表数据解析为DataFrame,支持指定工作表(sheet_name参数)、跳过行等高级操作。
返回值:pandas.DataFrame。
file_extension == '.xlsx':
return pd.read_excel(path,engine='openpyxl') # pandas本身不直接支持.xlsx格式,需依赖openpyxl作为引擎
elif file_extension == '.xlsx':
FileHandler._write_excel(path,data) # 自定义方法
@staticmethod
def _write_excel(path,data): # 加上_命名 表示这是类内部的私有方法仅限于类内部使用 不建议外部使用
"""将数据写入Excel文件"""
workbook = openpyxl.Workbook()
for sheet_name ,sheet_data in data.items():
worksheet = workbook.create_sheet(sheet_name)
for row in range(len(sheet_data)):
for col ,value in enumerate(sheet_data[row]):
worksheet.cell(row =row + 1,column = col + 1).value = value
workbook.save(path)
文件对应模块
以下是对列出的Python模块的详细介绍,包括核心功能、典型用途及简单示例:
1. yaml 模块
- 核心功能:用于解析和生成 YAML(YAML Ain’t Markup Language) 格式的文件。YAML是一种轻量级数据序列化格式,语法简洁易读,支持列表、字典、嵌套结构等,常作为配置文件或数据交换格式。
- 典型用途:
- 读取程序的配置文件(如
.yaml或.yml),获取数据库连接信息、路径配置等; - 将Python数据结构(字典、列表等)保存为YAML文件,便于人类阅读和编辑。
- 读取程序的配置文件(如
- 简单示例:
import yaml # 读取YAML文件 with open("config.yaml", "r") as f: config = yaml.safe_load(f) # 安全加载(避免代码注入风险) print(config["database"]["host"]) # 假设config.yaml中包含database: {host: "localhost"} # 生成YAML文件 data = {"name": "豆包", "hobbies": ["编程", "数据分析"]} with open("data.yml", "w") as f: yaml.dump(data, f, allow_unicode=True) # 保留中文
2. os 模块
- 核心功能:Python内置模块,用于与操作系统进行交互,提供文件/目录操作、环境变量访问、系统命令执行等功能。
- 典型用途:
- 处理文件路径(拼接、拆分、判断是否存在);
- 创建/删除目录、列出目录内容;
- 获取环境变量(如
os.environ.get("PATH")); - 执行系统命令(如
os.system("ls")在Linux中列出文件)。
- 简单示例:
import os # 拼接路径(跨平台兼容,自动处理斜杠) file_path = os.path.join("data", "result.csv") print(file_path) # 输出:data/result.csv(Linux/Mac)或 data\result.csv(Windows) # 判断文件是否存在,创建目录 if not os.path.exists("output"): os.mkdir("output") # 创建output目录 # 列出目录下的所有文件 print(os.listdir("data")) # 输出data目录中的文件/文件夹列表
3. pandas 模块
- 核心功能:Python数据分析与处理的核心库,提供高效的DataFrame(表格型数据)和Series(一维数组)数据结构,支持数据清洗、筛选、聚合、合并、读写文件等操作。
- 典型用途:
- 读取CSV、Excel、JSON等格式的结构化数据;
- 处理缺失值、去重、数据转换;
- 按条件筛选数据、分组统计(如
groupby); - 数据可视化的前置处理(结合
matplotlib/seaborn)。
- 简单示例:
import pandas as pd # 读取Excel文件(需配合openpyxl等引擎) df = pd.read_excel("sales.xlsx", sheet_name="2023") # 查看数据基本信息 print(df.head()) # 前5行 print(df.info()) # 列名、数据类型、缺失值统计 # 数据筛选:筛选销售额>1000的记录 high_sales = df[df["销售额"] > 1000] # 保存结果为CSV high_sales.to_csv("high_sales.csv", index=False)
4. openpyxl 模块
- 核心功能:专门用于读写 Excel 2007+ 版本(
.xlsx格式)的文件,支持单元格读写、工作表操作、格式设置(如字体、颜色)等细粒度控制。 - 典型用途:
- 当
pandas的Excel读写功能不足以满足需求时(如复杂格式、单元格样式修改); - 批量生成或修改Excel文件(如填充模板、合并单元格)。
- 当
- 简单示例:
from openpyxl import Workbook, load_workbook # 创建新Excel并写入数据 wb = Workbook() ws = wb.active # 获取当前工作表 ws["A1"] = "姓名" ws["B1"] = "年龄" ws.append(["豆包", 3]) # 追加一行 wb.save("info.xlsx") # 读取已有Excel并修改 wb = load_workbook("info.xlsx") ws = wb["Sheet"] # 选择工作表 ws["B2"] = 4 # 修改单元格值 wb.save("info_updated.xlsx")
5. configparser 模块
-
核心功能:用于处理 INI格式 的配置文件(常见后缀
.ini),支持按“节(section)”划分配置项,适合存储程序的配置信息(如数据库连接参数、API密钥)。 -
典型用途:
- 读取程序的配置参数(避免硬编码在代码中);
- 动态修改配置文件并保存。
-
简单示例:
假设config.ini内容如下:[database] host = localhost port = 3306 user = root password = 123456 [log] level = INFO path = logs/读取配置:
from configparser import ConfigParser cp = ConfigParser() cp.read("config.ini") # 读取配置文件 # 获取数据库配置 db_host = cp.get("database", "host") # 输出:localhost db_port = cp.getint("database", "port") # 转换为整数:3306 # 修改并保存配置 cp.set("log", "level", "DEBUG") # 修改log节的level with open("config.ini", "w") as f: cp.write(f) # 保存修改
项目完整代码
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2025/11/12 23:51
# @File :files.py
# @Author : 胜天半子
# IDE : PyCharm
# @CSDN : https://blog.csdn.net/HG0724?type=blog
import yaml # 用于解析和生成 YAML
import os
import pandas as pd # Python 数据分析与处理的核心库
import openpyxl # 用于写 Excel 2007+ 版本(.xlsx格式)的文件 pandas不支持写 xlsx文件
from configparser import ConfigParser # 用于处理 INI 格式 的配置文件(常见后缀.ini),支持按 “节(section)” 划分配置项
class FileHandler:
"""处理文件读取和写入操作的类"""
@staticmethod # 标记该方法是 “工具方法” 直接通过类名.方法名调用 FileHandler.read_file(...)
def read_file(path):
"""根据文件后缀的路径名称读取文件内容"""
# 分离文件名和后缀,统一转为小写(忽略大小写)
_,file_extension = os.path.splitext(path)
file_extension = file_extension.lower()
try:
if file_extension == '.yaml' or file_extension == '.yml': # 读取YAML文件,返回字典
with open(path,'r',encoding='UTF-8') as fp:
# 返回数据类型是dict
return yaml.safe_load(fp)
elif file_extension in ('.ini','.conf'):
config = ConfigParser()
with open(path,'r',encoding='UTF-8') as fp:
config.read_file(fp) # read_file读取的是流 fp
return config
elif file_extension == '.csv':
return pd.read_csv(path)
elif file_extension == '.xlsx':
return pd.read_excel(path,engine='openpyxl') # pandas本身不直接支持.xlsx格式,需依赖openpyxl作为引擎
else:
with open(path,'r',encoding='utf-8') as fp:
return fp.read()
except Exception as e :
print(f"Error reading file {path}:{e} !")
return None
@staticmethod
def write_file(path,data):
"""根据文件后缀的路径名称写入文件内容"""
# 分离文件名和后缀,统一转为小写(忽略大小写)
_,file_extension = os.path.splitext(path)
file_extension = file_extension.lower()
try:
if file_extension == '.yaml' or file_extension == '.yml': # 读取YAML文件,返回字典
with open(path,'r',encoding='UTF-8') as fp:
# 返回数据类型是dict
yaml.dump(data,fp,default_flow_style=False) # default_flow_style=False:生成 “块状” YAML(更易读),而非紧凑的 “流式” 格式。
elif file_extension in ('.ini','.conf'):
config = ConfigParser()
for section ,options in data.items():
config[section] = dict(options)
with open(path,'w',encoding='utf-8') as fp:
config.write(fp)
elif file_extension == '.csv':
pd.DataFrame(data).to_csv(path,index=False,encoding='utf-8')
elif file_extension == '.xlsx':
FileHandler._write_excel(path,data) # 自定义方法
else:
with open(path,'r',encoding='utf-8') as fp:
fp.write(str(data))
except Exception as e :
print(f"Error writing to file {path}:{e} !")
@staticmethod
def _write_excel(path,data): # 加上_命名 表示这是类内部的私有方法仅限于类内部使用 不建议外部使用
"""将数据写入Excel文件"""
workbook = openpyxl.Workbook()
for sheet_name ,sheet_data in data.items():
worksheet = workbook.create_sheet(sheet_name)
for row in range(len(sheet_data)):
for col ,value in enumerate(sheet_data[row]):
worksheet.cell(row =row + 1,column = col + 1).value = value
workbook.save(path)
# 测试使用
file_handler = FileHandler()
# yaml_data = file_handler.read_file('example_yaml.yaml')
# print(type(yaml_data))
# 格式化打印到控制台
# print(yaml.dump(yaml_data,
# allow_unicode=True, # 支持中文
# indent=2, # 缩进两个空格
# default_flow_style=False))
# ini_data = file_handler.read_file("example_ini.ini")
# print(ini_data['loggers']['keys'])
# conf_data = file_handler.read_file("example_conf.conf")
# print(conf_data['database'])
# print(conf_data['database']['user'])
# csv_data = file_handler.read_file('example.csv')
# print(csv_data)
# excel_data = file_handler.read_file('example.xlsx')
# print(excel_data)

被折叠的 条评论
为什么被折叠?



