Files
zclaw_openfang/docs/superpowers/specs/2026-04-10-e2e-comprehensive-test-design.md
iven 2e70e1a3f8
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
test: add 30 smoke tests for break detection across SaaS/Admin/Desktop
Layer 1 断裂探测矩阵:
- S1-S6: SaaS API 端到端 (auth/lockout/relay/permissions/billing/knowledge)
- A1-A6: Admin V2 连通性 (login/dashboard/CRUD/knowledge/roles/models)
- D1-D6: Desktop 聊天流 (gateway/kernel/relay/cancel/offline/error)
- F1-F6: Desktop 功能闭环 (agent/hands/pipeline/memory/butler/skills)
- X1-X6: 跨系统闭环 (provider→desktop/disabled user/knowledge/stats/totp/billing)

Also adds: admin-v2 Playwright config, updated spec doc with cross-reference

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-10 09:47:35 +08:00

440 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ZCLAW 全系统端到端测试方案
> **目标**: 设计覆盖 SaaS Admin + Tauri Desktop 的全面测试方案,验证所有功能形成闭环工作流
> **产出物**: 测试设计文档(本文件),指导后续测试执行
> **范围**: 功能测试 / 集成测试 / 端到端测试 / 数据一致性 / 权限验证
> **执行策略**: 本文档的详细测试矩阵由 [断裂探测测试方案](../../plans/noble-swinging-lynx.md) 驱动执行——先探测断裂,修复后按本文档做全面回归
---
## Context
ZCLAW 是一个三端系统Rust 后端(10 crates) + SaaS 后端(Axum+PostgreSQL, 119 API) + Admin V2(16页面) + Tauri 桌面端(React)。当前测试基线:
| 区域 | 现有测试 | 缺口 |
|------|----------|------|
| Rust crates | ~355 单元测试 | zclaw-saas/runtime/protocols 0 测试 |
| TypeScript Desktop | ~255 Vitest | 覆盖核心 store缺 Tauri IPC 层 |
| Admin V2 | 0 测试 | Vitest 已配置但无测试文件 |
| E2E | 5 Playwright 冒烟 | 仅 app shell 基础检查 |
| 跨系统 | 0 | 无 Admin→SaaS→Desktop 端到端验证 |
**核心问题**: 各子系统孤立测试,没有验证模块间的协同工作流。用户实际使用的是从 Admin 配置 → SaaS 存储 → Desktop 消费的完整链路。
---
## 一、测试基础设施搭建
### 1.1 SaaS 集成测试框架
**位置**: `crates/zclaw-saas/tests/`
- 复用 [main.rs](crates/zclaw-saas/src/main.rs) 中 `build_router()` 构建测试 Router
- 使用 `sqlx::test` + PostgreSQL 测试数据库(事务回滚隔离)
- 种子数据 fixture: super_admin/admin/user 三种角色 + 基础 Provider/Model
- 环境配置: `ZCLAW_SAAS_DEV=true` + 测试专用密钥
**关键参考文件**:
- 路由构建: [main.rs](crates/zclaw-saas/src/main.rs) `build_router()`
- 应用状态: [state.rs](crates/zclaw-saas/src/state.rs) `AppState`
- 错误类型: [error.rs](crates/zclaw-saas/src/error.rs) `SaasError`
### 1.2 Admin V2 测试框架
**位置**: `admin-v2/tests/`
已有: `@testing-library/react` + `msw` + `vitest` 已配置。需搭建:
- MSW handler 集合: 模拟 119 个 SaaS API 端点
- 自定义 `render()` 函数(包裹 QueryClientProvider + Router
- 种子数据工厂函数
**关键参考文件**:
- API 层: [admin-v2/src/services/request.ts](admin-v2/src/services/request.ts)Axios + 401 刷新)
- 18 个 service 文件: [admin-v2/src/services/](admin-v2/src/services/)
- 16 个页面: [admin-v2/src/pages/](admin-v2/src/pages/)
### 1.3 跨系统 E2E 框架
**位置**: `tests/cross-system/`
- Playwright 双 targetAdmin V2 + Desktop
- SaaS API 测试客户端TypeScript HTTP 封装)
- 数据库状态断言工具(直查 PostgreSQL
- 测试数据清理机制
---
## 二、功能测试(按模块)
### 2.1 SaaS API — Auth 模块 (10 端点) — P0
**源文件**: [crates/zclaw-saas/src/auth/handlers.rs](crates/zclaw-saas/src/auth/handlers.rs)
| 测试组 | 关键用例 | 边界/异常 |
|--------|----------|-----------|
| 注册 | 正常注册→JWT+cookies角色固定 user | 用户名 3/32/33 字符;密码 7/8/128/129 字符;邮箱格式;重复用户名 409 |
| 登录 | 正确密码→JWT+refresh+HttpOnly cookies | 错误密码 401不存在的用户 401不泄露信息禁用账号 403 |
| 账号锁定 | 5 次失败→locked_until=now+15min | 锁定期内正确密码仍 40115min 后解锁 |
| TOTP 2FA | setup→verify→login with code→disable | 未提供码 400错误码 400secret 加密存储(enc:前缀) |
| Token 刷新 | 有效 refresh_token→新 token 对 | 一次性使用(第二次 401);过期 token 401 |
| 修改密码 | 正确旧密码→pwv 递增 | 改密码后旧 access token 401(pwv 不匹配) |
| 登出 | refresh token 标记 used + cookies 清除 | 登出后再刷新 401 |
### 2.2 SaaS API — Account 模块 (11 端点) — P0
**源文件**: [crates/zclaw-saas/src/account/handlers.rs](crates/zclaw-saas/src/account/handlers.rs)
| 测试组 | 关键用例 |
|--------|----------|
| 列表/详情 | admin 分页列表user 查自己 200user 查他人 403 |
| 更新 | admin 修改角色成功user 修改自己时 role 字段被忽略(防权限提升) |
| 状态管理 | admin 禁用/启用 user |
| 仪表盘 | dashboard stats 字段完整性 |
| 操作日志 | 分页 + action/target_type/timestamp |
### 2.3 SaaS API — Model Config 模块 (21 端点) — P0
**源文件**: [crates/zclaw-saas/src/model_config/](crates/zclaw-saas/src/model_config/)
| 测试组 | 关键用例 |
|--------|----------|
| Provider CRUD | 创建(含 base_url 验证)更新禁用→relay 不可用;删除(级联行为) |
| Model CRUD | 创建(关联 provider)provider 不存在→404禁用→relay 不列出 |
| Model Group | 创建组+成员failover 排序全部禁用→404 |
| Key Pool | 添加 key(>20 字符验证)加密存储toggle active删除 |
### 2.4 SaaS API — Relay 模块 (5 端点) — P0
**源文件**: [crates/zclaw-saas/src/relay/handlers.rs](crates/zclaw-saas/src/relay/handlers.rs)
| 测试组 | 关键用例 |
|--------|----------|
| Chat 非流式 | 正常 JSON 响应 |
| Chat 流式 SSE | `text/event-stream` 格式 |
| 输入验证 | 缺 model 400空 messages 400无效 role 400temperature 0~2 边界max_tokens 1~128000 |
| 模型解析 | Direct model→路由到 providerGroup model→failover 选择 |
| 错误场景 | 模型不存在 404provider 禁用 403队列满 429 |
| 任务管理 | user 只看自己的任务;非 admin 看他人任务 403重试仅 failed 状态 |
### 2.5 SaaS API — 其他模块
| 模块 | 端点数 | 优先级 | 关键测试点 |
|------|--------|--------|-----------|
| Billing | 10 | P1 | 计划列表/订阅/用量/配额检查/支付 |
| Knowledge | 21 | P0 | 分类 CRUD/条目 CRUD/搜索/版本/语义搜索 |
| Prompt | 9 | P1 | 模板 CRUD/OTA 批量检查/版本回滚 |
| Role | 7 | P0 | 角色 CRUD/权限模板/应用模板 |
| Config | 8 | P2 | 配置项 CRUD/sync/diff |
| Agent Template | 9 | P1 | 模板 CRUD/分配 |
| Scheduled Task | 4 | P2 | 任务 CRUD |
| Telemetry | 4 | P2 | 上报/统计(500 条截断) |
### 2.6 Admin V2 页面功能测试
**框架**: Vitest + Testing Library + MSW
| 页面 | 优先级 | 关键测试点 |
|------|--------|-----------|
| Login | P0 | 表单渲染/正常登录/错误提示/TOTP 动态显示/URL 重定向 |
| Dashboard | P1 | 5 个统计卡片/操作日志/加载失败 ErrorState |
| Accounts | P0 | 表格渲染/搜索/编辑弹窗/角色修改/禁用启用 |
| Knowledge | P0 | 分类树/CRUD/搜索结果 |
| ModelServices | P0 | Provider/Model/Key Pool 管理 |
| Roles | P0 | 角色 CRUD/权限编辑 |
| Relay | P0 | 任务列表/重试/模型列表 |
| Billing | P1 | 计划/订阅/用量展示 |
| Usage | P1 | 用量统计图表 |
| Prompts | P1 | 模板列表/版本历史 |
| Config | P2 | 配置项 CRUD/sync 日志 |
| ScheduledTasks | P2 | 任务管理 |
| ConfigSync | P2 | 同步日志 |
| Logs | P2 | 操作日志筛选 |
每个页面测试覆盖:加载渲染 → 数据展示 → 表单提交 → 错误处理 → 导航跳转。
### 2.7 Tauri 子系统功能测试
| 子系统 | 优先级 | 关键测试点 | 关键文件 |
|--------|--------|-----------|---------|
| Chat (3模式) | P0 | Gateway WS / Kernel Event / SaaS Relay SSE | [desktop/src/lib/](desktop/src/lib/) |
| Memory | P0 | 提取→FTS5→检索→注入闭环 | [crates/zclaw-growth/](crates/zclaw-growth/) |
| Agent | P1 | 创建/切换/人格/身份 | [desktop/src-tauri/src/kernel_commands/agent.rs](desktop/src-tauri/src/kernel_commands/agent.rs) |
| Pipeline | P1 | 模板加载→DAG 解析→执行 | [crates/zclaw-pipeline/](crates/zclaw-pipeline/) |
| Hands | P1 | 触发/参数/审批/执行 | [crates/zclaw-hands/](crates/zclaw-hands/) |
| Butler | P1 | 路由分类/冷启动/痛点持久化 | [desktop/src-tauri/src/intelligence/](desktop/src-tauri/src/intelligence/) |
---
## 三、集成测试(模块交互)
### 3.1 Auth → 权限执行全覆盖 — P0
**方法**: 参数化测试,角色 × 端点 × 预期状态码矩阵
| 角色 | 验证策略 |
|------|----------|
| super_admin (admin:full) | 全部 119 端点 200/201 |
| admin (细分权限) | 有权限 200无权限 403 |
| user (最小权限) | relay:use + knowledge:read + 自身信息,其余 403 |
| 未认证 | 公开端点 200受保护 401 |
| API Token | zclaw_ 前缀 token 按 token 权限验证 |
**核心**: [auth/mod.rs](crates/zclaw-saas/src/auth/mod.rs) 中 `auth_middleware()` 的 JWT/API Token 双路径 + `check_permission()` 的 admin:full 通配逻辑
### 3.2 Admin 配置 → SaaS DB → Desktop 行为 — P0
| Admin 操作 | SaaS DB 变化 | Desktop 验证 |
|------------|-------------|-------------|
| 新增 Provider+Model | providers/models 表新增行 | relay/models 列表包含新模型 |
| 禁用 Provider | enabled=false | 列表不显示该 Provider 的模型 |
| 修改用户配额 | billing_plans 更新 | relay 请求受新配额约束 |
| 创建知识条目 | knowledge_items 新增 | Agent 能检索到新知识 |
**注意**: SaaS 缓存 60s 刷新间隔,测试需等待或手动触发刷新。
### 3.3 Chat 完整流程 — P0
```
Desktop (saas-relay.ts chatCompletion)
→ POST /relay/chat/completions
→ SaaS: 验证权限 + 配额
→ SaaS: 解析模型(Direct/Group) → 路由到 Provider
→ SaaS: 创建 relay_task (status=queued)
→ SaaS: 转发到 LLM Provider (base_url)
→ Provider: SSE 流响应
→ SaaS: 透传 SSE + 记录 usage
→ SaaS: relay_task status=completed
→ Desktop: 流式显示响应
```
验证点: 每个环节的数据状态。关键文件: [relay/handlers.rs](crates/zclaw-saas/src/relay/handlers.rs), [saas-relay.ts](desktop/src/lib/saas-relay.ts)
### 3.4 Memory Pipeline 闭环 — P1
```
对话 → MemoryExtractor 提取 → FTS5 全文索引 → Retriever 检索 → 注入 system prompt
```
验证: 对话后 30s(防抖) 检查 FTS5 索引内容;下次对话时 Agent 使用记忆回答。
### 3.5 Pipeline 执行 — P1
```
模板加载 → YAML 解析 → DAG 依赖排序 → 节点执行 → 结果汇总
```
---
## 四、端到端测试(完整业务流程)
### E2E-1: 用户生命周期 — P0
```
Admin 创建用户 → 用户登录 → 查看 relay/models → 发送聊天 → 记录 usage
→ Admin 查看 Usage 页面 → Dashboard 统计更新
```
验证: JWT 签发、relay_task 创建、billing_usage 递增、Dashboard 今日统计+1
### E2E-2: Provider/Model 配置到使用 — P0
```
Admin 创建 Provider → 添加 API Key(加密存储) → 创建 Model → [等60s缓存刷新]
→ Desktop 获取模型列表 → 使用新模型聊天 → SaaS 正确路由
```
验证: DB 中 key_value 为密文、relay_task 记录正确 provider_id
### E2E-3: 知识库配置到检索 — P1
```
Admin 创建分类 → 创建知识条目(含 tags) → SaaS 生成 embedding
→ Desktop Agent 对话中检索知识库 → 回答包含知识库内容
```
验证: knowledge_items.embedding 非空、回答内容与知识条目相关
### E2E-4: 完整注册到回访 — P1
```
注册 → 登录 → auth/me → relay/models → 首次聊天 → 记忆提取(FTS5)
→ 登出 → 登录 → 利用记忆回答
```
验证: role=user、relay_task+usage 递增、FTS5 索引、记忆引用
### E2E-5: 权限变更生效 — P0
```
Admin 修改 user 角色 permissions → user 下次请求使用新权限
→ 验证: 原来允许的端点变为 403 或原来禁止的变为 200
```
---
## 五、数据一致性测试
### 5.1 Admin 资源变更 → Desktop 感知 — P0
| 资源 | 变更操作 | Desktop 感知 | 一致性窗口 |
|------|----------|-------------|-----------|
| Provider | 创建/禁用 | relay/models 列表更新 | ≤60s |
| Model | 创建/修改 | 模型列表+详情 | ≤60s |
| 角色权限 | 修改 permissions | 用户下次请求新权限 | 即时(JWT内嵌) |
| 配额 | 修改 billing_plan | 下次请求新配额 | 即时 |
### 5.2 计费与请求数一致性 — P0
```sql
-- 验证 relay 请求数
SELECT COUNT(*) FROM relay_tasks WHERE account_id = $1 AND status = 'completed'
-- 应等于
SELECT relay_requests FROM billing_usage WHERE account_id = $1
```
| 测试点 | 验证 |
|--------|------|
| 成功请求计数 | billing_usage.relay_requests = 实际成功数 |
| 失败请求不计费 | relay_task.status=failed 不增加 usage |
| Token 用量准确 | input_tokens + output_tokens 与 LLM 返回一致 |
| SSE 流式 token 后修正 | AggregateUsageWorker 对账后更新 |
### 5.3 Dashboard 统计准确性 — P1
| 统计项 | 数据源 SQL | 验证 |
|--------|-----------|------|
| total_accounts | `SELECT COUNT(*) FROM accounts` | 一致 |
| active_providers | `... WHERE enabled=true` | 一致 |
| tasks_today | `... WHERE created_at >= today` | 一致 |
| tokens_today | `SUM(input_tokens + output_tokens)` | 一致 |
### 5.4 知识搜索准确性 — P1
| 输入 | 预期 |
|------|------|
| 精确关键词 "API Key" | 含该关键词的条目排前 |
| 语义查询 "如何配置密钥" | "API Key 配置指南" 排前 |
| 分类过滤 | 仅返回指定分类结果 |
| 空结果查询 | 空列表(不报错) |
---
## 六、权限验证测试
### 6.1 角色权限矩阵 — P0
| 端点类别 | super_admin | admin | user | 未认证 |
|----------|:-----------:|:-----:|:----:|:------:|
| POST /auth/register | - | - | - | 200 |
| POST /auth/login | - | - | - | 200 |
| GET /auth/me | 200 | 200 | 200 | 401 |
| PUT /auth/password | 200 | 200 | 200 | 401 |
| GET /accounts | 200 | 200 | **403** | 401 |
| POST /providers | 200 | 200* | **403** | 401 |
| POST /models | 200 | 200* | **403** | 401 |
| POST /relay/chat/completions | 200 | 200 | 200** | 401 |
| POST /relay/tasks/:id/retry | 200 | 200* | **403** | 401 |
| POST /knowledge/items | 200 | 200* | **403** | 401 |
| GET /roles | 200 | 200 | **403** | 401 |
*需要对应细分权限provider:manage/model:manage 等)
**需要 relay:use 权限
### 6.2 Token 生命周期 — P0
| 场景 | 预期 |
|------|------|
| Access token 2h 内 | 200 |
| Access token 过期 | 401 |
| Refresh token 7d 内 | 新 token 对 |
| Refresh 一次性使用 | 第二次 401 |
| 密码修改后旧 token | 401 (pwv 不匹配) |
| 登出后 refresh | 401 |
### 6.3 账号锁定 — P0
| 步骤 | 预期 |
|------|------|
| 第 1-4 次错误密码 | 401, failed_login_count 递增 |
| 第 5 次错误 | locked_until = now+15min |
| 锁定期内正确密码 | 仍 401 |
| 15min 后 | 登录成功, count 重置 |
### 6.4 速率限制 — P1
| 端点 | 限制 | 超限响应 |
|------|------|---------|
| POST /auth/login | 5次/分/IP | 429 |
| POST /auth/register | 3次/小时/IP | 429 |
| POST 端点 (通用) | RPM 配置值 | 429 |
| GET 端点 | 无限制 | - |
---
## 七、实施路线图
### Phase 1: P0 核心测试
1. **SaaS 集成测试框架** — 搭建 test_app + 种子数据 + 事务回滚
2. **Auth 模块全量** — 注册/登录/TOTP/锁定/Token 生命周期
3. **权限矩阵参数化** — 119 端点 × 4 角色
4. **Relay 模块核心** — 流式/非流式/模型解析/输入验证
5. **Admin V2 关键页面** — Login/Accounts/Knowledge/ModelServices/Relay
6. **E2E 用户生命周期** — 创建→登录→聊天→查看用量
### Phase 2: P1 扩展测试
1. Model Config / Billing / Prompt / Role 模块测试
2. Desktop Store 补充测试
3. 跨系统 E2E (Playwright)
4. 计费一致性验证
5. 知识搜索准确性
### Phase 3: P2 补全测试
1. Config/Telemetry/Scheduled Task 模块
2. Admin V2 剩余页面
3. Pipeline/Hooks 系统
4. 性能/压力测试
---
## 八、风险与缓解
| 风险 | 缓解 |
|------|------|
| SaaS 集成测试需 PostgreSQL | GitHub Actions postgres service / Docker |
| SSE 流式测试断言难 | tokio stream 收集完整响应后断言 |
| 缓存刷新 60s 延迟 | 测试中手动触发缓存刷新或直接调用 load_from_db |
| TOTP 码时间敏感 | mock totp_rs 或使用已知 secret 固定码 |
| Playwright flaky | wait_for 替代 sleep + 重试机制 |
---
## 九、验证方法
测试完成后通过以下命令验证:
```bash
# SaaS 集成测试
cargo test -p zclaw-saas -- --test-threads=1
# Admin V2 单元测试
cd admin-v2 && pnpm vitest run
# Desktop 前端测试
cd desktop && pnpm vitest run
# E2E 测试
pnpm test:e2e
# 类型检查
pnpm tsc --noEmit
```
**测试报告交付物**:
- 功能覆盖矩阵(模块 × 通过/失败/未测试)
- 模块协同状态评估(集成路径 × 验证结果)
- 发现的问题清单(优先级 + 重现步骤)
- 改进建议(测试基础设施 + 代码质量)