在 Python 接口自动化框架中封装读取 Excel 表格的方法,核心目标是把 Excel 中的测试用例数据(如接口地址、请求方法、参数、预期结果等)读取出来并转换成结构化的格式(如字典列表),方便自动化脚本调用,同时保证方法的健壮性和易用性。

我会基于常用的 openpyxl 库(支持.xlsx 格式,是接口自动化的主流选择)来封装一个通用的 Excel 读取类,包含「读取指定 sheet」「读取指定行 / 列」「返回结构化测试用例」等核心功能,兼顾异常处理和易用性。

一、前置准备

首先安装依赖库(openpyxl 专门处理.xlsx 文件,是接口自动化的首选):

bash

pip install openpyxl

二、完整封装代码

python

import os
from openpyxl import load_workbook

class ExcelReader:
    """
    Excel读取工具类(适配接口自动化测试用例读取)
    支持:读取指定sheet、返回字典列表格式的测试用例、读取指定行/列数据
    """
    def __init__(self, file_path):
        """
        初始化Excel读取器
        :param file_path: Excel文件路径(绝对/相对路径)
        """
        # 校验文件是否存在
        if not os.path.exists(file_path):
            raise FileNotFoundError(f"Excel文件不存在:{file_path}")
        # 校验文件格式(仅支持.xlsx)
        if not file_path.endswith(".xlsx"):
            raise ValueError("仅支持读取.xlsx格式的Excel文件,若为.xls请使用xlrd库")
        
        self.file_path = file_path
        # 加载工作簿(read_only=True提升大文件读取性能,data_only=True读取单元格值而非公式)
        self.workbook = load_workbook(self.file_path, read_only=True, data_only=True)

    def get_sheet_names(self):
        """获取Excel中所有sheet名称"""
        return self.workbook.sheetnames

    def read_sheet_data(self, sheet_name=None, skip_header=True):
        """
        读取指定sheet的所有数据,返回字典列表(核心方法)
        :param sheet_name: 要读取的sheet名称,默认读取第一个sheet
        :param skip_header: 是否跳过表头(True:表头作为字典的key,False:包含表头行)
        :return: 字典列表,例:[{"url": "/login", "method": "POST", "params": "{'username':'test'}"}, ...]
        """
        # 若未指定sheet,取第一个sheet
        if not sheet_name:
            sheet_name = self.get_sheet_names()[0]
        
        # 校验sheet是否存在
        if sheet_name not in self.get_sheet_names():
            raise ValueError(f"sheet名称不存在:{sheet_name},所有sheet:{self.get_sheet_names()}")
        
        sheet = self.workbook[sheet_name]
        # 获取最大行、最大列(确定数据范围)
        max_row = sheet.max_row
        max_col = sheet.max_column

        # 空sheet处理
        if max_row == 0:
            return []
        
        # 读取表头(第一行)
        headers = []
        for col in range(1, max_col + 1):
            header_value = sheet.cell(row=1, column=col).value
            headers.append(header_value if header_value else f"col_{col}")  # 空表头默认命名为col_数字
        
        # 读取数据行
        data_list = []
        # 起始行:skip_header=True则从第2行开始,否则从第1行开始
        start_row = 2 if skip_header else 1
        
        for row in range(start_row, max_row + 1):
            row_data = {}
            for col in range(1, max_col + 1):
                cell_value = sheet.cell(row=row, column=col).value
                # 空单元格默认赋值为空字符串,避免None值影响后续处理
                row_data[headers[col - 1]] = cell_value if cell_value is not None else ""
            data_list.append(row_data)
        
        return data_list

    def read_specific_row(self, sheet_name=None, row_num=1):
        """
        读取指定行的数据
        :param sheet_name: sheet名称,默认第一个
        :param row_num: 行号(从1开始)
        :return: 该行的字典数据(表头为key)
        """
        # 先读取所有数据,再取指定行
        all_data = self.read_sheet_data(sheet_name, skip_header=True)
        # 行号转换:row_num=2 对应 all_data[0](因为跳过了表头)
        index = row_num - 2
        if index < 0 or index >= len(all_data):
            raise IndexError(f"行号超出范围,当前sheet最大数据行:{len(all_data) + 1}")
        return all_data[index]

    def close(self):
        """关闭工作簿,释放资源"""
        self.workbook.close()

# ------------------- 上下文管理器封装(可选,自动关闭文件) -------------------
class ExcelReaderContext:
    def __init__(self, file_path):
        self.file_path = file_path
        self.reader = None

    def __enter__(self):
        self.reader = ExcelReader(self.file_path)
        return self.reader

    def __exit__(self, exc_type, exc_val, exc_tb):
        if self.reader:
            self.reader.close()

# ------------------- 调用示例 -------------------
if __name__ == "__main__":
    # 示例1:基础调用(手动关闭)
    try:
        excel_reader = ExcelReader("test_cases.xlsx")
        # 读取第一个sheet的测试用例
        test_cases = excel_reader.read_sheet_data()
        print("所有测试用例:")
        for case in test_cases:
            print(case)
        
        # 读取指定sheet(如"登录接口")的用例
        login_cases = excel_reader.read_sheet_data(sheet_name="登录接口")
        print("\n登录接口用例:", login_cases)
        
        # 读取指定行(如第3行)的用例
        third_case = excel_reader.read_specific_row(row_num=3)
        print("\n第3行用例:", third_case)
    finally:
        excel_reader.close()

    # 示例2:上下文管理器调用(自动关闭,推荐)
    with ExcelReaderContext("test_cases.xlsx") as reader:
        data = reader.read_sheet_data(sheet_name="支付接口")
        print("\n支付接口用例:", data)

三、代码关键说明

1. 核心功能解析

  • 初始化校验:提前校验文件是否存在、格式是否为.xlsx,避免运行中报错;
  • read_sheet_data(核心)
    • 自动将表头作为字典的 key,每行数据作为 value,返回结构化的字典列表(最适合接口自动化读取测试用例);
    • skip_header=True 跳过表头行,直接返回测试用例数据(符合自动化场景);
    • 空单元格默认赋值为空字符串,避免后续处理 None 值的麻烦;
  • read_specific_row:读取指定行的用例,适合单条用例调试;
  • 上下文管理器ExcelReaderContext 封装,自动关闭工作簿,避免资源泄漏(推荐使用)。

2. 适配接口自动化的场景

假设你的 Excel 测试用例格式如下:

urlmethodparamsexpected_codeexpected_msg
/api/loginPOST{"username":"test"}200登录成功
/api/userGET{"uid":123}200查询成功

调用 read_sheet_data() 后,返回的数据格式为:

python

[
    {
        "url": "/api/login",
        "method": "POST",
        "params": "{'username':'test'}",
        "expected_code": 200,
        "expected_msg": "登录成功"
    },
    {
        "url": "/api/user",
        "method": "GET",
        "params": "{'uid':123}",
        "expected_code": 200,
        "expected_msg": "查询成功"
    }
]

这种格式可以直接遍历,传入接口请求方法(如 requests.post/get)中执行自动化测试。

3. 扩展优化(可选)

  • 参数类型转换:Excel 中读取的参数是字符串,可在方法内增加 eval() 或 json.loads() 转换为字典:

    python

    import json
    # 在read_sheet_data的row_data赋值处增加:
    if headers[col - 1] == "params":
        try:
            cell_value = json.loads(cell_value)  # 转换为字典
        except:
            cell_value = eval(cell_value)  # 备选方案
    
  • 支持.xls 格式:若需要读取.xls 文件,可替换为 xlrd 库(注意:xlrd 2.0+ 不支持.xlsx,需安装 xlrd==1.2.0);
  • 写入 Excel:可扩展 write_data 方法,用于写入测试结果(如实际响应码、是否通过)。

四、使用注意事项

  1. Excel 文件路径建议使用绝对路径(接口自动化框架中可配置全局路径常量);
  2. 表头命名要规范(如 url、method、params),与代码中调用的 key 保持一致;
  3. 大文件读取时,read_only=True 已开启,无需额外优化;
  4. 用完后必须关闭工作簿(上下文管理器会自动处理),否则可能导致文件被占用无法修改。

总结

  1. 封装的 ExcelReader 类核心是将 Excel 测试用例转换为字典列表,适配接口自动化的参数传递场景;
  2. 内置文件校验、空值处理、资源自动释放,保证方法的健壮性;
  3. 优先使用 with ExcelReaderContext(...) 方式调用,自动关闭文件,简化代码;
  4. 可扩展参数类型转换、结果写入等功能,适配更复杂的接口自动化场景。
Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐