mirror of
https://github.com/fastapiadmin/FastapiAdmin.git
synced 2026-09-21 12:52:26 +00:00
refactor: 迁移前端资源文件至web目录 feat: 新增多种图标资源 style: 统一代码风格和格式化配置 docs: 更新README和文档说明 chore: 更新依赖和配置文件 fix: 修复部分类型定义和枚举 perf: 优化路由和组件加载逻辑
119 lines
4.0 KiB
Python
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)
|