# PRD - 性能测试模块需求文档

> **文档版本**: v1.0
> **创建日期**: 2026-08-12
> **模块类型**: 性能测试
> **优先级**: P1

---

## 一、背景与目标

### 1.1 背景

当前平台已实现 UI 自动化测试、安全测试等功能，覆盖了功能正确性和安全性验证。但在实际项目交付中，还需要对系统进行**性能测试**，确保系统在高并发场景下的稳定性和响应能力。

被测系统（统一管理平台 https://192.168.5.44）采用微前端 micro-app 架构，接口层使用复杂的 AES-CBC 签名 + SHA256 验证机制（X-RANDOM、X-TIMESTAMP、X-SIGN、RandomCode 头部），登录流程还需验证码 UUID 获取。现有平台 `HttpClient` 已完整实现了该认证体系，性能测试模块需复用这一能力。

### 1.2 目标

将性能测试能力集成到现有平台，实现：

1. **统一入口**: 性能测试用例与 UI/安全用例统一管理，通过 `case_type=performance` 筛选
2. **可视化配置**: 前端界面配置并发数、QPS 目标、压测时长等参数
3. **实时监控**: 执行过程中实时推送 TPS、响应时间、错误率等指标
4. **标准化报告**: 生成性能测试报告，含吞吐量、延迟分布、错误分析等
5. **结果可验证**: 确保执行结果正确，支持断言判断接口响应是否符合预期

---

## 二、功能范围

### 2.1 核心功能

| 功能 | 描述 | 优先级 |
|------|------|--------|
| 性能测试任务管理 | 创建/编辑/删除性能测试任务 | P0 |
| 性能测试执行引擎 | 轻量级 asyncio + aiohttp 并发引擎 | P0 |
| 实时指标推送 | WebSocket 推送 TPS/响应时间/错误率 | P0 |
| 性能测试报告 | 可视化报告（吞吐量、延迟分布、错误分析） | P0 |
| 性能测试用例管理 | 复用现有 TestCase 模型，case_type=performance | P1 |
| 断言验证 | 支持状态码/响应体/响应时间断言 | P1 |
| 多场景配置 | 支持阶梯加压、并发模式、固定 QPS 模式 | P1 |
| 历史对比 | 多次执行结果对比分析 | P2 |

### 2.2 性能指标覆盖

| 指标 | 说明 | 采集方式 |
|------|------|---------|
| TPS/QPS | 每秒事务数/请求数 | 引擎实时统计 |
| 响应时间 (ms) | 最小/平均/最大/P50/P90/P99 | 引擎实时统计 |
| 错误率 | 失败请求占比 | 引擎实时统计 |
| 并发数 | 当前活跃虚拟用户数 | 引擎实时统计 |
| 状态码分布 | 2xx/3xx/4xx/5xx 分布 | 引擎实时统计 |
| 时间序列 | 随时间变化的指标曲线 | 定期采样（默认1s） |

---

## 三、详细需求

### 3.1 性能测试任务模型

#### 3.1.1 PerformanceTask

性能测试任务是一个独立实体，与现有 TestCase 模型解耦，因为性能测试的配置参数远多于普通用例。

```python
class PerformanceTask(Base):
    """
    性能测试任务模型
    
    每次性能测试执行对应一个任务，包含压测配置和结果统计。
    """
    __tablename__ = "performance_tasks"
    
    id: str  # 唯一标识 (perf_xxx)
    name: str  # 任务名称
    description: str  # 任务描述
    status: str  # pending/running/completed/failed/cancelled
    
    # 目标配置
    target_url: str  # 目标接口完整URL
    method: str  # HTTP方法 (GET/POST/PUT/DELETE)
    headers: dict  # 自定义请求头
    body: dict  # 请求体（JSON）
    body_template: dict  # 请求体模板（支持变量替换）
    
    # 压测配置
    mode: str  # 模式: concurrent(并发模式)/qps(固定QPS)/step(阶梯加压)
    concurrency: int  # 并发数（并发模式）
    qps_target: int  # 目标QPS（QPS模式）
    duration: int  # 压测时长（秒）
    ramp_up: int  # 预热时间（秒）
    step_concurrency: list  # 阶梯并发配置，如 [10, 50, 100, 200]
    step_duration: int  # 每阶梯持续时间（秒）
    
    # 认证配置
    auth_required: bool  # 是否需要登录Token
    account_key: str  # 使用的账号 (superadmin/admin/user)
    
    # 断言配置
    assertions: list  # 断言规则列表
    
    # 结果统计
    total_requests: int  # 总请求数
    success_count: int  # 成功数
    fail_count: int  # 失败数
    min_response_time: float  # 最小响应时间(ms)
    max_response_time: float  # 最大响应时间(ms)
    avg_response_time: float  # 平均响应时间(ms)
    p50_response_time: float  # P50响应时间(ms)
    p90_response_time: float  # P90响应时间(ms)
    p99_response_time: float  # P99响应时间(ms)
    actual_tps: float  # 实际吞吐量
    error_rate: float  # 错误率
    
    # 时间
    start_time: datetime
    end_time: datetime
    duration_actual: float  # 实际耗时（秒）
    created_at: datetime
    updated_at: datetime
```

#### 3.1.2 PerformanceSnapshot

性能快照模型，用于存储时间序列数据，支持实时图表和历史回放。

```python
class PerformanceSnapshot(Base):
    """
    性能快照模型
    
    每秒钟采集一次性能指标，用于实时监控和历史回放。
    """
    __tablename__ = "performance_snapshots"
    
    id: int  # 自增主键
    task_id: str  # 关联任务ID
    timestamp: float  # 采集时间戳（秒）
    elapsed: float  # 距开始时间（秒）
    concurrent_users: int  # 当前并发数
    tps: float  # 当前吞吐量
    avg_response_time: float  # 平均响应时间
    min_response_time: float  # 最小响应时间
    max_response_time: float  # 最大响应时间
    p50_response_time: float  # P50
    p90_response_time: float  # P90
    p99_response_time: float  # P99
    success_count: int  # 成功请求数（本周期内）
    fail_count: int  # 失败请求数（本周期内）
    status_2xx: int  # 2xx状态码计数
    status_3xx: int  # 3xx状态码计数
    status_4xx: int  # 4xx状态码计数
    status_5xx: int  # 5xx状态码计数
```

### 3.2 性能测试执行引擎

#### 3.2.1 架构设计

```
PerformanceExecutor
├── HttpClient（复用现有实现）
│   ├── 自动签名（AES-CBC）
│   ├── Token 管理（调用登录接口获取）
│   └── 请求发送
├── ConcurrencyEngine（轻量级 asyncio + aiohttp）
│   ├── 并发模式：固定并发数发送请求
│   ├── QPS模式：定时器控制请求速率
│   └── 阶梯模式：逐步增加并发数
├── MetricsCollector
│   ├── 实时指标采集（每秒统计）
│   ├── 延迟分布计算（P50/P90/P99）
│   └── 错误率统计
└── ResultValidator
    ├── 状态码断言
    ├── 响应体断言
    └── 响应时间断言
```

#### 3.2.2 执行流程

```
1. 初始化 PerformanceExecutor
2. 若 auth_required=True，调用 HttpClient.login() 获取 Token
3. 构造请求（签名头部 + Token）
4. 启动 MetricsCollector（每秒采集）
5. 根据 mode 启动并发引擎：
   a. concurrent: 创建 N 个协程并发发送请求
   b. qps: 通过 asyncio.sleep 控制发送速率
   c. step: 按阶梯递增并发数
6. 每个请求执行：
   a. 发送 HTTP 请求（aiohttp）
   b. 记录响应时间
   c. 执行断言验证
   d. 更新计数器
7. 到达 duration 后停止
8. 计算最终统计指标
9. 保存结果到数据库
10. 通过 WebSocket 推送完成通知
```

#### 3.2.3 关键约束

- **Token 获取**: 通过调用登录接口获取（复用 HttpClient.login()），不硬编码 Token
- **执行结果正确性**: 每个请求执行断言验证（状态码、响应体、响应时间），确保压测结果准确
- **轻量级**: 不依赖 JMeter/Locust 等重型工具，使用 asyncio + aiohttp 自研轻量引擎
- **资源控制**: 限制最大并发数（默认 500），避免压垮本地环境
- **错误处理**: 网络超时、连接错误等异常不会导致整体失败，计入错误统计

### 3.3 性能测试断言

每个性能测试任务可配置断言规则，用于判断接口响应是否正确：

```json
[
  {
    "type": "status_code",
    "operator": "equals",
    "value": 200,
    "description": "响应状态码应为200"
  },
  {
    "type": "response_body",
    "operator": "json_path",
    "path": "$.code",
    "value": 200,
    "description": "业务码应为200"
  },
  {
    "type": "response_time",
    "operator": "less_than",
    "value": 3000,
    "description": "响应时间应小于3秒"
  }
]
```

断言失败的请求计入错误统计，但不会中断压测（与 UI 测试不同，性能测试需要持续运行以采集完整数据）。

### 3.4 实时监控与推送

#### 3.4.1 WebSocket 消息格式

```json
{
  "type": "performance_snapshot",
  "task_id": "perf_xxx",
  "data": {
    "elapsed": 5.2,
    "concurrent_users": 50,
    "tps": 123.45,
    "avg_response_time": 245.6,
    "p50": 180.0,
    "p90": 450.0,
    "p99": 1200.0,
    "success_count": 600,
    "fail_count": 3,
    "status_2xx": 598,
    "status_4xx": 2,
    "status_5xx": 1,
    "total_requests": 603
  }
}
```

推送频率：每秒一次（与 MetricsCollector 采样频率一致）。

#### 3.4.2 事件类型

| 事件 | 触发时机 | 说明 |
|------|---------|------|
| perf_start | 压测开始 | 携带任务配置信息 |
| perf_snapshot | 每秒 | 实时性能指标 |
| perf_assert_fail | 断言失败时 | 单次请求断言失败 |
| perf_complete | 压测完成 | 最终统计结果 |
| perf_error | 执行异常 | 错误信息 |

### 3.5 前端页面

#### 3.5.1 性能测试任务列表

- 展示所有性能测试任务，支持按状态筛选
- 卡片或列表视图，显示关键指标（TPS、响应时间、错误率）
- 操作：新建、执行、查看报告、删除

#### 3.5.2 性能测试任务配置

- 目标接口配置（URL、方法、请求头、请求体）
- 压测模式选择（并发/QPS/阶梯）
- 参数配置（并发数、时长、预热时间等）
- 认证配置（是否需要登录、使用哪个账号）
- 断言配置（状态码、响应体、响应时间）

#### 3.5.3 实时监控页面

- TPS 实时曲线图
- 响应时间实时曲线图（平均/P50/P90/P99）
- 并发数实时曲线图
- 状态码分布实时饼图
- 实时统计面板（总请求数、成功/失败、错误率）
- 控制按钮（停止执行）

#### 3.5.4 性能测试报告

- 执行概览（任务信息、压测配置、结果摘要）
- 吞吐量图表
- 延迟分布图表（含 P50/P90/P99 标注）
- 时间序列图表（TPS/响应时间随时间变化）
- 状态码分布
- 错误详情列表
- 导出功能（Markdown/JSON）

---

## 四、非功能需求

### 4.1 性能约束

- 引擎自身开销 < 5%（相对于目标 QPS）
- 单机最大并发数：500（可根据配置调整）
- 采样精度：每秒一次
- 响应时间精度：毫秒级

### 4.2 兼容性

- 复用现有 HttpClient 的签名和认证逻辑
- 适配被测系统的复杂认证流程（AES-CBC + SHA256）
- 支持 HTTP/HTTPS

### 4.3 安全性

- Token 只在内存中使用，不持久化到数据库
- 压测目标限于内网系统（https://192.168.5.44）

---

## 五、现有资产复用

| 现有资产 | 用途 | 复用方式 |
|---------|------|---------|
| `HttpClient` | 登录获取 Token、请求签名 | 直接复用，不修改 |
| `TestCase` (case_type=performance) | 性能测试用例管理 | 扩展使用 |
| WebSocket Manager | 实时推送 | 直接复用 |
| 报告生成工具 | 报告生成 | 扩展支持性能报告 |
| Execution 模型 | 执行记录 | 扩展 case_type=performance |

---

## 六、风险与缓解

| 风险 | 影响 | 缓解措施 |
|------|------|---------|
| 被测系统性能瓶颈导致误判 | 测试结果不准确 | 多次执行取平均值 |
| 本地网络波动影响结果 | 响应时间偏差 | 增加预热时间，取稳定段数据 |
| Token 过期 | 请求失败 | 实现自动刷新 Token 机制 |
| 高并发时数据库写锁 | 快照丢失 | 使用批量写入，降低写入频率 |
| 被测系统熔断/限流 | 误判为系统问题 | 区分 503/429 与真正的错误 |

---

*本文档为性能测试模块的需求定义，后续将输出计划执行文档用于指导开发。*