# HANDOFF_性能测试

> 生成时间：2026-08-12 15:00
> 当前分支：`platform-auto-test`
> 最近提交：`09346c8e feat(element-mapping): 元素映射表扩展至v1.2`
> 主分支：`master`

---

## 整体状态

| 阶段 | 状态 | 说明 |
|------|------|------|
| Phase 1 - 数据模型 + Schema | ✅ 完成 | ORM 模型 + Pydantic 校验 |
| Phase 2 - 压测执行引擎 | ✅ 完成 | 轻量级 asyncio + aiohttp 自研引擎 |
| Phase 3 - 后端路由 + Service | ✅ 完成 | 11 个 API 路由 + Service 层 |
| Phase 4 - 前端页面 | ✅ 完成 | 任务管理/监控/报告 三个面板 |
| Phase 5 - 集成测试 | ⏳ 待做 | 端到端验证（创建→执行→监控→报告） |

**后端代码行数**：2173 行（executor 748 + service 588 + router 296 + model 279 + schema 262）
**前端代码行数**：1768 行（index 98 + TaskList 476 + MonitorPanel 459 + ReportPanel 373 + api 121 + types 241）

---

## 多窗口并行开发注意

如需同时开多个 Claude Code 窗口开发不同子菜单功能，请先阅读 `Docs/多窗口并行开发指南.md`。

性能测试模块的端口与文件：
- 后端：8001（默认）/ 8002（当前可用）
- 前端：3000
- 数据库：`data/test_platform.db`（共享同一个 SQLite）
- Git 分支：`platform-auto-test`

---

## 已完成事项

### 后端（Phase 1-3）

#### 1. 数据模型 (`backend/app/models/performance.py`)

| 模型 | 表名 | 说明 |
|------|------|------|
| `PerformanceTask` | `performance_tasks` | 任务主表（名称/URL/方法/模式/并发/时长/状态/认证/断言） |
| `PerformanceSnapshot` | `performance_snapshots` | 每秒快照（TPS/响应时间P50/P90/P99/状态码分布） |
| `PerformanceTaskResult` | `performance_task_results` | 最终结果（汇总指标 + JSON 详情） |

**关键字段**：
- `PerformanceTask.mode` → `concurrent` / `qps` / `step`
- `PerformanceTask.status` → `pending` / `running` / `completed` / `failed` / `cancelled`
- `PerformanceTask.account_key` → `superadmin` / `admin` / `user`
- `PerformanceSnapshot` 使用 camelCase 别名（`p50_response_time` → `p50` / `p90` / `p99`）

#### 2. Pydantic Schema (`backend/app/schemas/performance.py`)

- 全部 schema 使用 `populate_by_name=True, alias_generator=to_camel` 实现 camelCase 兼容
- 断言规则：`AssertionRule`（status_code / response_time / response_body + JSON Path）
- 请求/响应结构：`PerformanceTaskCreate` / `PerformanceTaskUpdate` / `PerformanceTaskResponse` / `PerformanceTaskListItem` / `PerformanceTaskListResponse`
- 执行相关：`PerformanceRunRequest` / `PerformanceRunResponse`
- 数据：`PerformanceSnapshotResponse` / `PerformanceSnapshotListResponse`
- 报告：`PerformanceReportResponse`（含 `summary` / `metrics` / `snapshots`）

#### 3. 压测执行引擎 (`backend/app/executors/performance_executor.py`)

**核心架构**：
- `MetricsCollector` — 线程安全指标采集器（带锁的 period 累积 + 全局累加）
  - `record()` 记录单次请求结果（响应时间 + 状态码 + 错误）
  - `snapshot()` 生成每秒快照（TPS / P50/P90/P99 / 状态码分布）
  - `summary()` 汇总最终指标
  - `snapshot_callback` 实时推送（WebSocket 每 1 秒回调）
- `ResultValidator` — 三种断言类型（status_code / response_time / response_body JSON Path）
- `PerformanceExecutor` — 主执行器
  - `execute()` 入口：Token 获取 → 并发执行 → 指标采集 → 断言验证
  - 使用 `HttpClient`（`app.executors.http_client`）获取 Token
  - 三种模式：
    - **concurrent**：固定并发数，持续 duration 秒
    - **qps**：固定 QPS 限流，持续 duration 秒
    - **step**：阶梯并发，每 step_duration 秒递增 step_concurrency
  - 通过 `asyncio.Event` 实现优雅停止
  - 预热阶段（ramp_up）逐步增加并发

**运行模式（Windows 兼容）**：
- 引擎运行在独立线程中
- `asyncio.set_event_loop(None)` → `new_event_loop()` → `run_until_complete(executor.execute())`
- 复用 `playwright_executor.py` 已验证的 Windows 兼容模式

#### 4. Service 层 (`backend/app/services/performance_service.py`)

**CRUD 操作**：
- `create_task()` / `get_task()` / `list_tasks()` / `update_task()` / `delete_task()`

**执行控制**：
- `run_task()` — 启动执行（`_run_sync` 线程池模式）
- `stop_task()` — 发送停止信号（`asyncio.Event.set()`）
- `_run_sync()` — 线程内执行完整流程（登录 → 执行 → 保存快照/结果 → 更新状态）
- `_running_executors: Dict[str, PerformanceExecutor]` 类缓存跟踪运行中任务

**数据查询**：
- `get_snapshots()` / `get_report()` / `get_task_results()`

**认证配置**：
```python
_DEFAULT_BASE_URL = "https://192.168.5.44"
_DEFAULT_ACCOUNTS = {
    "superadmin": {"username": "admin@xty", "password": "Ubains@13579"},
    "admin": {"username": "admin@xty", "password": "Ubains@13579"},
    "user": {"username": "admin@xty", "password": "Ubains@13579"},
}
```
- 验证码固定 `csba`
- 认证路径：`/platform/api/auth/login`
- 验证码路径：`/platform/api/code`
- Token 通过 `HttpClient.login(account_key)` 获取 → 注入请求头

#### 5. API 路由 (`backend/app/routers/performance.py`)

前缀 `/api/performance`，注册于 `main.py` 第 216-219 行，tags `["性能测试"]`

| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/api/performance/tasks` | 任务列表（分页 + 状态过滤） |
| POST | `/api/performance/tasks` | 创建任务 |
| GET | `/api/performance/tasks/{task_id}` | 获取单个任务 |
| PUT | `/api/performance/tasks/{task_id}` | 更新任务 |
| DELETE | `/api/performance/tasks/{task_id}` | 删除任务 |
| POST | `/api/performance/tasks/{task_id}/run` | 执行任务 |
| POST | `/api/performance/tasks/{task_id}/stop` | 停止任务 |
| GET | `/api/performance/tasks/{task_id}/snapshots` | 获取快照列表 |
| GET | `/api/performance/tasks/{task_id}/report` | 获取报告 |
| GET | `/api/performance/tasks/{task_id}/results` | 获取执行结果 |
| WS | `/api/performance/ws/{task_id}` | 实时监控 WebSocket |

**WebSocket**：
- 端点：`/api/performance/ws/{task_id}`
- 分组名：`perf_{task_id}`
- 复用 `app/websocket/manager.py` 的 `ConnectionManager`
- 推送格式：执行器每秒回调的 JSON 快照

#### 6. 后端注册 (`backend/app/main.py`)

```python
from app.routers import performance as performance_router
# ...
app.include_router(performance_router.router, prefix="/api/performance", tags=["性能测试"])
```

### 前端（Phase 4）

#### 1. 路由 (`frontend/src/router/index.ts`)

```
/performance → Performance index.vue (懒加载)
/cases/performance → redirect /performance
/execution/performance → redirect /performance
/reports/performance → redirect /performance
```

#### 2. 菜单 (`frontend/src/App.vue`)

三个侧边栏菜单项指向 `/performance`：
- 用例管理 → 性能测试
- 执行中心 → 性能测试
- 报告中心 → 性能测试

#### 3. 主容器 (`frontend/src/views/performance/index.vue`)

三个 el-tabs：任务管理 / 执行监控 / 报告查看
- 状态管理：`monitorTaskId`、`reportTaskId`
- Tab 切换时联动（点击"监控"→ 切换到监控 tab 并传入 taskId）
- 通过 `defineExpose` 暴露 `loadReport()` / `refresh()`

#### 4. 任务列表 (`frontend/src/views/performance/TaskList.vue`)

- el-table 展示：名称/URL/方法/模式/并发/时长/状态/TPS/错误率/创建时间
- 操作列：执行/停止/监控/报告/编辑/删除
- 状态过滤下拉框 + 分页
- 创建/编辑弹窗（el-dialog）：名称/URL/方法/模式/并发/时长/预热/QPS目标/阶梯并发/请求头/请求体/认证开关/账号选择/描述
- 表单校验：名称/URL/方法/模式 必填
- `defineEmits<{ viewMonitor: [taskId: string]; viewReport: [taskId: string] }>()`

#### 5. 实时监控 (`frontend/src/views/performance/MonitorPanel.vue`)

- WebSocket 实时连接（`createPerfMonitorStream`）
- 三张 ECharts 图表：TPS 趋势（折线图 + 面积渐变）/ 响应时间趋势（平均/P50/P90/P99 四条线）/ 状态码分布（环形饼图）
- 顶部 4 个指标卡片：当前 TPS / 平均响应时间 / 总请求数 / 错误率
- 连接状态指示器（绿/黄/灰圆点）
- 数据缓冲区上限 300 点，先进先出
- 自动断开处理 + 错误提示

#### 6. 报告查看 (`frontend/src/views/performance/ReportPanel.vue`)

- 执行摘要（el-descriptions：任务名/URL/方法/模式/并发数/账号/开始/结束/实际时长）
- 核心指标卡片（8 个）：总请求数/成功数/失败数/错误率/TPS/平均/最小/最大响应时间
- 响应时间分位数表（P50/P90/P99）
- 状态码分布表（2xx/3xx/4xx/5xx + 数量 + 占比）
- TPS 趋势图 + 响应时间趋势图（ECharts）
- 导出 JSON 功能

#### 7. API 封装 (`frontend/src/api/performance.ts`)

```typescript
BASE = '/api/performance'
listTasks(params) → GET /tasks
getTask(id) → GET /tasks/{id}
createTask(data) → POST /tasks
updateTask(id, data) → PUT /tasks/{id}
deleteTask(id) → DELETE /tasks/{id}
runTask(id) → POST /tasks/{id}/run
stopTask(id) → POST /tasks/{id}/stop
getSnapshots(id) → GET /tasks/{id}/snapshots
getReport(id) → GET /tasks/{id}/report
getTaskResults(id) → GET /tasks/{id}/results
createPerfMonitorStream(id, onSnapshot, onComplete, onError, onClose) → WebSocket
```

#### 8. 类型定义 (`frontend/src/types/performance.ts`)

所有接口类型（camelCase 风格）：
- `PerformanceTask` / `PerformanceTaskListItem` / `PerformanceTaskCreate`
- `PerformanceSnapshot` / `PerformanceSnapshotListResponse`
- `PerformanceReportResponse` / `PerformanceReportSummary` / `PerformanceReportMetrics`
- `AssertionRule`
- `PerformanceRunRequest` / `PerformanceRunResponse`

#### 9. 前端构建验证

```bash
cd frontend && npm run build
# ✓ 构建成功 (34.48s), 无 TypeScript 错误
```

---

## 错误修复记录

### 1. 后端 404 / OpenAPI 不显示性能测试路由

**现象**：访问 `http://localhost:8001/docs` 看不到性能测试 API，`/api/performance/tasks` 返回 404

**根因**：运行在 8001 端口的 uvicorn 是**旧进程**（PID 10912，启动于 2026-08-11 15:50），早于性能模块代码的编写时间。代码中的 `performance` 路由注册在 `main.py` 中，但旧进程加载的是旧代码。

**验证**：通过 Python 直接 import 确认路由注册正确：
```python
from app.main import app
routes = [r.path for r in app.routes if "/api/performance" in str(r.path)]
# 输出: 11 条路由，全部正确
```

**修复**：尝试 kill 旧进程失败（access denied / not found），改用端口 8002 启动新后端。已验证 8002 正常工作。

### 2. 无法 kill 旧 uvicorn 进程

**尝试过的方法**（全部失败）：
- `taskkill /F /PID 10912` → 访问被拒绝
- `taskkill /F /PID 27100` → 未找到进程
- PowerShell `Stop-Process` → not found
- `kill -9` → no such process
- `os.kill(pid, 9)` → WinError 5 拒绝访问
- `wmic` → not found in bash

**原因**：进程由不同上下文的用户启动（可能是通过 Windows 服务或 Administrator 启动的），当前 bash 会话无权限操作。

**当前解决**：使用端口 8002 启动新后端：
```bash
cd backend && uvicorn app.main:app --reload --port 8002
```

### 3. 前端 TS 类型错误（本会话前已修复）

- TS6133: `emit` 未使用 → 移除
- TS2339: `tasks`/`total` 找不到 → 修复类型定义
- TS2345: `string | null` 不能赋值给 `string` → 修复 `formatTime` 参数类型

---

## 当前运行状态

### 后端
- 8001 端口：旧进程（含旧代码），无法关闭
- 8002 端口：新后端正常运行 ✅
  - `GET /api/performance/tasks` → `{"total":0,"items":[]}` 正常
  - `http://localhost:8002/docs` → OpenAPI 包含性能测试路由

### 前端
- `http://localhost:3000` → 正常
- `npm run build` → 构建通过（34.48s）

---

## 未提交的代码

性能测试模块代码尚未 commit。影响文件：

```
# 后端新文件
backend/app/executors/performance_executor.py       (NEW)
backend/app/services/performance_service.py          (NEW)
backend/app/routers/performance.py                   (NEW)
backend/app/models/performance.py                    (NEW)
backend/app/schemas/performance.py                   (NEW)
backend/app/main.py                                  (MODIFIED: 注册 performance router)

# 前端新文件
frontend/src/views/performance/index.vue             (NEW)
frontend/src/views/performance/TaskList.vue          (NEW)
frontend/src/views/performance/MonitorPanel.vue      (NEW)
frontend/src/views/performance/ReportPanel.vue       (NEW)
frontend/src/api/performance.ts                      (NEW)
frontend/src/types/performance.ts                    (NEW)
frontend/src/router/index.ts                         (MODIFIED: 添加 /performance 路由)
frontend/src/App.vue                                 (MODIFIED: 添加侧边栏菜单项)
```

---

## 下一步任务

### Phase 5 - 集成测试（P0）

端到端验证流程：

1. **创建任务** → POST `/api/performance/tasks`
   - 使用 `admin@xty` / `Ubains@13579` / 验证码 `csba`
   - 目标 URL：被测系统真实接口（如 `/platform/api/xxx`）
   - 模式：concurrent（并发 10，时长 60s）

2. **执行任务** → POST `/api/performance/tasks/{id}/run`
   - 验证返回 `{"message": "任务已开始执行"}`
   - 验证状态变为 `running`

3. **实时监控** → WebSocket `/api/performance/ws/{task_id}`
   - 验证每秒收到快照数据
   - 验证 TPS / 响应时间 / 状态码 数据合理

4. **任务完成** → 等待状态变为 `completed`
   - 验证 `error_message` 为 null
   - 验证 `actual_tps` 不为 null

5. **查看报告** → GET `/api/performance/tasks/{id}/report`
   - 验证摘要、指标、快照数据完整
   - 验证 P50/P90/P99 分位数合理

6. **查看快照** → GET `/api/performance/tasks/{id}/snapshots`
   - 验证快照数量 ≈ 压测时长

7. **前端验证**
   - 任务列表显示正确
   - 监控面板实时图表渲染
   - 报告面板数据展示

### 后续优化（P1）

- 断言规则验证（`ResultValidator` 需要在执行中启用）
- 更详细的错误处理（Token 过期重试、网络错误分类）
- 报告对比功能（多次执行结果对比）
- 批量导出报告
- 压力测试数据清理（定期清理旧快照）

---

*本文档由 Claude Code 自动生成，用于多会话协作开发时的上下文传递。*