feat(admin): 添加用户管理相关文件

添加用户管理视图、API和状态管理文件
This commit is contained in:
张翔
2026-03-28 14:37:29 +08:00
commit 08ea5fbe98
1643 changed files with 255646 additions and 0 deletions
@@ -0,0 +1,38 @@
class APITestException(Exception):
"""API测试基础异常"""
pass
class ConfigException(APITestException):
"""配置异常"""
pass
class DataException(APITestException):
"""数据异常"""
pass
class AuthException(APITestException):
"""认证异常"""
pass
class RequestException(APITestException):
"""请求异常"""
pass
class ValidationException(APITestException):
"""验证异常"""
pass
class TestRunException(APITestException):
"""测试执行异常"""
pass
class ReportException(APITestException):
"""报告生成异常"""
pass
@@ -0,0 +1,151 @@
from enum import Enum
from typing import Any, Dict, List, Optional
from dataclasses import dataclass, field
from datetime import datetime
class HTTPMethod(Enum):
"""HTTP方法枚举"""
GET = "GET"
POST = "POST"
PUT = "PUT"
DELETE = "DELETE"
PATCH = "PATCH"
HEAD = "HEAD"
OPTIONS = "OPTIONS"
@dataclass(frozen=True)
class ValidationRule:
"""验证规则数据模型"""
type: str # status_code, json_path, contains, regex, schema
expected: Any
json_path: Optional[str] = None
message: Optional[str] = None
@dataclass(frozen=True)
class TestCase:
"""测试用例数据模型"""
id: str # 用例唯一标识
name: str # 用例名称
description: str # 用例描述
module: str # 所属模块
endpoint: str # API端点
method: HTTPMethod # HTTP方法
headers: Dict[str, str] # 请求头
params: Optional[Dict[str, Any]] = None # URL参数
body: Optional[Dict[str, Any]] = None # 请求体
auth_required: bool = True # 是否需要认证
dependencies: List[str] = None # 依赖的用例ID
timeout: int = 5000 # 超时时间(毫秒)
retry_count: int = 0 # 重试次数
validations: List[Dict] = None # 验证规则
setup: Optional[Dict] = None # 前置操作
teardown: Optional[Dict] = None # 后置操作
tags: List[str] = None # 标签
priority: int = 0 # 优先级
enabled: bool = True # 是否启用
def __post_init__(self):
if self.dependencies is None:
object.__setattr__(self, "dependencies", [])
if self.validations is None:
object.__setattr__(self, "validations", [])
if self.tags is None:
object.__setattr__(self, "tags", [])
@dataclass
class PerformanceMetrics:
"""性能指标数据模型"""
response_time: int # 响应时间(毫秒)
request_size: int # 请求大小(字节)
response_size: int # 响应大小(字节)
timestamp: datetime # 时间戳
def to_dict(self) -> Dict[str, Any]:
"""转换为字典"""
return {
"response_time": self.response_time,
"request_size": self.request_size,
"response_size": self.response_size,
"timestamp": self.timestamp.isoformat()
}
@dataclass
class TestResult:
"""测试结果数据模型"""
test_case: TestCase # 测试用例
passed: bool # 是否通过
status_code: int # HTTP状态码
response_body: Any # 响应体
response_headers: Dict[str, str] # 响应头
error_message: Optional[str] = None # 错误消息
performance: Optional[PerformanceMetrics] = None # 性能指标
execution_time: float = 0.0 # 执行时间(秒)
retry_count: int = 0 # 重试次数
timestamp: datetime = None # 执行时间戳
def __post_init__(self):
if self.timestamp is None:
self.timestamp = datetime.now()
def to_dict(self) -> Dict[str, Any]:
"""转换为字典"""
return {
"test_case_id": self.test_case.id,
"test_case_name": self.test_case.name,
"passed": self.passed,
"status_code": self.status_code,
"response_body": self.response_body,
"response_headers": self.response_headers,
"error_message": self.error_message,
"performance": self.performance.to_dict() if self.performance else None,
"execution_time": self.execution_time,
"retry_count": self.retry_count,
"timestamp": self.timestamp.isoformat()
}
@dataclass
class TestSuiteResult:
"""测试套件结果数据模型"""
suite_name: str # 套件名称
total: int # 总数
passed: int # 通过数
failed: int # 失败数
skipped: int # 跳过数
results: List[TestResult] # 测试结果列表
start_time: datetime # 开始时间
end_time: Optional[datetime] = None # 结束时间
@property
def duration(self) -> float:
"""执行时长(秒)"""
if self.end_time:
return (self.end_time - self.start_time).total_seconds()
return 0.0
@property
def pass_rate(self) -> float:
"""通过率"""
if self.total == 0:
return 0.0
return (self.passed / self.total) * 100
def to_dict(self) -> Dict[str, Any]:
"""转换为字典"""
return {
"suite_name": self.suite_name,
"total": self.total,
"passed": self.passed,
"failed": self.failed,
"skipped": self.skipped,
"pass_rate": self.pass_rate,
"duration": self.duration,
"start_time": self.start_time.isoformat(),
"end_time": self.end_time.isoformat() if self.end_time else None,
"results": [result.to_dict() for result in self.results]
}