Files
FastapiAdmin/backend/tests/tools/excel_tool.py
T
zhangtao 80263e98e1 feat: 重构前端项目结构并优化代码
refactor: 迁移前端资源文件至web目录
feat: 新增多种图标资源
style: 统一代码风格和格式化配置
docs: 更新README和文档说明
chore: 更新依赖和配置文件
fix: 修复部分类型定义和枚举
perf: 优化路由和组件加载逻辑
2026-05-01 01:01:17 +08:00

119 lines
4.0 KiB
Python

# -*- coding: utf-8 -*-
import json
from typing import Dict, List, Optional
import pandas as pd
from openpyxl.styles import Font
from openpyxl import load_workbook
import logging
class ExcelPack:
# Excel列结构配置
COLUMNS = {
'name': 0,
'run': 1,
'token': 2,
'url': 3,
'data': 4,
'method': 5,
'type': 6,
'header': 7,
'code': 8,
'isSuccess': 9,
'result': 10,
}
# 结果样式配置
STYLES = {
'pass': (3, '00FF00'), # 绿色
'fail': (4, 'FF0000'), # 红色
'skip': (6, '800080'), # 紫色
}
def __init__(self, file_name: str, api_host: str, token: str):
self.file_name = file_name
self._df = None
self.api_host = api_host
self.token = token
@property
def df(self) -> pd.DataFrame:
if self._df is None:
self._df = pd.read_excel(self.file_name)
logging.info(f"成功读取Excel文件: {self.file_name}")
return self._df
def _get_cell_value(self, row: int, col_name: str) -> str:
"""统一的单元格获取方法"""
value = self.df.iloc[row, self.COLUMNS[col_name]]
return str(value).strip() if pd.notna(value) else ''
def _write_cell(self, row: int, col_name: str, value: str, style: Optional[int] = None):
"""增量更新单元格内容,保留其他数据格式"""
# 更新DataFrame中的值
col = self.COLUMNS[col_name]
self.df.iloc[row, col] = value
# 直接加载工作簿进行更新
workbook = load_workbook(self.file_name)
worksheet = workbook.active
# 写入新值
cell = worksheet.cell(row=row + 2, column=col + 1)
cell.value = value
# 应用样式
if style and isinstance(style, (int, str)):
style_config = self.STYLES.get(str(style))
if style_config and len(style_config) >= 2:
color = style_config[1]
cell.font = Font(bold=True, color=color)
else:
logging.warning(f"无效的样式配置: {style}")
# 保存工作簿
workbook.save(self.file_name)
def load_test_cases(self) -> List[Dict]:
"""加载测试用例"""
test_cases = []
for row in range(1, len(self.df)):
headers = eval(self._get_cell_value(row, 'header')) if self._get_cell_value(row, 'header') else {}
if self._get_cell_value(row, 'token').lower() == 'yes':
headers['token'] = self.token
case = {
'name': self._get_cell_value(row, 'name'),
'run': self._get_cell_value(row, 'run'),
'token': self._get_cell_value(row, 'token'),
'type': self._get_cell_value(row, 'type'),
'request': {
'url': f"{self.api_host}{self._get_cell_value(row, 'url')}",
'method': self._get_cell_value(row, 'method'),
'headers': headers,
'data': json.loads(self._get_cell_value(row, 'data')) if self._get_cell_value(row, 'data') else None,
},
'expected': {
'code': int(self._get_cell_value(row, 'code')),
'isSuccess': bool(self._get_cell_value(row, 'isSuccess')),
},
'result': {
'result': self._get_cell_value(row, 'result'),
},
'row': row,
}
test_cases.append(case)
return test_cases
def write_to_excel(self, row: int, result: Dict) -> None:
"""写入结果到Excel"""
try:
# 更新数据
self._write_cell(row, 'result', result['result'], result['result'])
logging.info(f"测试结果写入成功: {result['name']}")
except Exception as e:
logging.error(f"写入测试结果失败: {str(e)}")
logging.exception(e)