Files
Nexus/docs/testing/test-case-matrix.md
T
Nexus Agent 0f6f91e61a fix(api): align alerts/commands contracts and ship full-site test suite.
Restore alert history filters and stats fields, paginate command/session logs for the SPA, show script labels on schedules, and land integration/E2E coverage with rebuilt web assets.
2026-06-09 02:13:13 +08:00

258 lines
13 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.
# Nexus 全站测试用例矩阵(SSOT)
> 编号规则:`<层>-<域>-<序号>`
> 层:`UT` 单元 · `IT` 集成 · `CH` 链条 · `E2E` Playwright · `MCP` Agent 浏览器
> 状态:`✅` 已有 · `🔲` 待写 · `🟡` 部分覆盖 · `⏭` 不验收(已确认豁免)
最后更新:2026-06-09
---
## 0. 横切能力
| ID | 层 | 用例 | 前置 | 步骤 | 期望 | 状态 | 实现位置 |
|----|-----|------|------|------|------|------|----------|
| UT-AUTH-001 | UT | JWT access 过期边界 | 固定 clock | 签发 exp-1s token | 401 + 中文提示 | ✅ | test_login_access.py |
| UT-AUTH-002 | UT | refresh 复用检测 | 双 refresh 同 jti | 第二次 refresh | 401 revoke 全家 | ✅ | test_auth_refresh_reuse.py |
| UT-VAL-001 | UT | 422 loc 中文化 | — | per_page=999 | detail 含 `每页条数` | ✅ | test_validation_errors_zh.py |
| UT-TIME-001 | UT | 北京时间格式化 | UTC 输入 | format_display_time | `Asia/Shanghai` 字符串 | ✅ | test_display_time.py |
| UT-SEC-001 | UT | 路径穿越拒绝 | — | `../etc/passwd` | ValidationError | ✅ | test_remote_path_validation.py |
| IT-AUTH-001 | IT | 登录换 token | API 活 | POST /api/auth/login | access+refresh | ✅ | test_api.py |
| IT-AUTH-002 | IT | 无 token 403 | — | GET /api/servers | 401/403 | ✅ | test_api.py |
| CH-AUTH-001 | CH | 登录→刷新→访问 | 活 API | login→refresh→GET servers | 200 | ✅ | tests/chain/test_auth_flow.py |
| E2E-AUTH-001 | E2E | 错误密码 | 浏览器 | 填错密码登录 | 页内错误提示 | ✅ | e2e/pages/auth.spec.mjs |
| MCP-AUTH-001 | MCP | 登录页渲染 | base URL | snapshot #/login | 表单+品牌可见 | ✅ | e2e/pages/login.spec.mjs |
---
## 1. 安装向导 `/app/install.html`
| ID | 层 | 用例 | 期望 | 状态 | 备注 |
|----|-----|------|------|------|------|
| UT-INST-001 | UT | 已安装锁 404 | /api/install/* 404 | ✅ | test_install_locked_404.py |
| IT-INST-001 | IT | 无 .env 仅 install 路由 | /health 与 /api/servers 行为 | ✅ | tests/integration/test_install_mode.py |
| E2E-INST-001 | E2E | 安装页可打开 | install.html 200 | ✅ | e2e/pages/install.spec.mjs |
| MCP-INST-001 | MCP | 安装步骤 UI | 各 step 控件可见 | ⏭ | **不验收**:生产已锁安装向导;E2E-INST-001 可达性已够 |
---
## 2. 仪表盘 Dashboard `#/`
| ID | 层 | 用例 | 期望 | 状态 | 实现 |
|----|-----|------|------|------|------|
| IT-DASH-001 | IT | GET /api/dashboard/stats | 200 + 数字字段 | ✅ | tests/integration/test_servers_dashboard.py |
| E2E-DASH-001 | E2E | 仪表盘加载 | 卡片/图表区域可见 | ✅ | full-acceptance #2 + dashboard-stats.spec.mjs |
| MCP-DASH-001 | MCP | 统计数字非空 | 在线/告警计数 | ✅ | 沉淀 E2E-DASH-001 |
---
## 3. 服务器 Servers `#/servers`
| ID | 层 | 用例 | 期望 | 状态 | 实现 |
|----|-----|------|------|------|------|
| UT-SRV-001 | UT | 列表排序键合法 | sort 白名单 | ✅ | test_server_list_sort.py |
| UT-SRV-002 | UT | status 字段枚举 | online/offline/… | ✅ | test_server_status_field.py |
| UT-SRV-003 | UT | target_path 过滤 | 非法路径拒绝 | ✅ | test_server_target_path_filter.py |
| IT-SRV-001 | IT | GET /api/servers 分页 | total+items | ✅ | test_api.py |
| IT-SRV-002 | IT | per_page>200 → 422 中文 | loc_zh | ✅ | 422 改造后 |
| IT-SRV-003 | IT | notify 开关 settings API | 审计+CUD | ✅ | tests/integration/test_notify_settings.py |
| CH-SRV-001 | CH | 列表→详情抽屉→保存 | DB 与响应一致 | ✅ | tests/chain/test_server_update_flow.py |
| E2E-SRV-001 | E2E | 表格+筛选 | 表头+搜索框 | ✅ | full-acceptance #3 |
| E2E-SRV-002 | E2E | **无 CSV 导出按钮** | 按钮不存在 | ✅ | e2e/pages/servers.spec.mjs |
| E2E-SRV-003 | E2E | 分类筛选可见 | chip/文案 | ✅ | e2e/pages/servers-filter.spec.mjs |
| MCP-SRV-001 | MCP | 打开筛选抽屉 | 分类/状态 chip | ✅ | 沉淀 E2E-SRV-003 |
---
## 4. 终端 Terminal `#/terminal`
| ID | 层 | 用例 | 期望 | 状态 | 实现 |
|----|-----|------|------|------|------|
| UT-TERM-001 | UT | WebSSH payload 校验 | 非法 host 拒绝 | ✅ | test_webssh_terminal_payload.py |
| IT-TERM-001 | IT | WS /ws/webssh 握手 | 401 无 token | ✅ | tests/integration/test_webssh_auth.py |
| E2E-TERM-001 | E2E | 页加载 idle 提示 | 未选服务器文案 | ✅ | e2e/pages/terminal.spec.mjs |
| MCP-TERM-001 | MCP | 选子机不连真 SSH | UI 状态 idle | ✅ | 沉淀 e2e/pages/terminal.spec.mjs |
---
## 5. 文件 Files `#/files`
| ID | 层 | 用例 | 期望 | 状态 | 实现 |
|----|-----|------|------|------|------|
| UT-FILE-001 | UT | ls 解析 | unix ls 输出 | ✅ | test_unix_ls.py |
| UT-FILE-002 | UT | browse etag | 304 条件 | ✅ | test_files_browse_etag.py |
| UT-FILE-003 | UT | 提权路径策略 | sudo 边界 | ✅ | test_files_elevation.py |
| IT-FILE-001 | IT | GET browse | 列表 JSON | ✅ | tests/integration/test_files_browse.py |
| CH-FILE-001 | CH | 浏览→上传 staging→确认 | staging 清理 | ✅ | tests/chain/test_file_staging_flow.py |
| E2E-FILE-001 | E2E | 文件页表格 | 路径栏可见 | ✅ | e2e/pages/files.spec.mjs |
| MCP-FILE-001 | MCP | 目录树展开一级 | 无 500 toast | ✅ | 沉淀 e2e/pages/files.spec.mjs |
---
## 6. 推送 Push `#/push`
| ID | 层 | 用例 | 期望 | 状态 | 实现 |
|----|-----|------|------|------|------|
| UT-PUSH-001 | UT | batch_id 生成唯一 | UUID 格式 | ✅ | test_sync_batch_id.py |
| UT-PUSH-002 | UT | rsync 权限位 | 映射正确 | ✅ | test_rsync_push_permissions.py |
| UT-PUSH-003 | UT | upload form 字段 | schema | ✅ | test_sync_upload_form.py |
| IT-PUSH-001 | IT | POST sync 立即 accepted | `accepted:true` 非阻塞 | ✅ | tests/integration/test_push_sync.py |
| IT-PUSH-002 | IT | GET /api/sync/logs | 分页 | ✅ | tests/integration/test_servers_dashboard.py |
| CH-PUSH-001 | CH | accepted→WS progress→log 行 | batch 状态终态 | ✅ | tests/chain/test_push_async_flow.py |
| E2E-PUSH-001 | E2E | 推送页控件 | 目标路径+提交 | ✅ | full-acceptance #6 |
| E2E-PUSH-002 | E2E | 提交后短暂 loading 非一直转圈 | submitting 结束 | ✅ | e2e/pages/push.spec.mjs |
| MCP-PUSH-001 | MCP | 选测试子机 dry-run 提交 | toast + 进度表 | ✅ | e2e/pages/push.spec.mjsmock 子机+API |
---
## 7. 脚本 Scripts `#/scripts`
| ID | 层 | 用例 | 期望 | 状态 | 实现 |
|----|-----|------|------|------|------|
| UT-SCR-001 | UT | dispatch 路由 | server_ids 校验 | ✅ | test_script_dispatch.py |
| IT-SCR-001 | IT | CRUD /api/scripts | 201/200/404 | ✅ | tests/integration/test_scripts_executions.py |
| E2E-SCR-001 | E2E | 脚本列表+新建按钮 | 无 JS 错误 | ✅ | e2e/pages/scripts.spec.mjs |
| MCP-SCR-001 | MCP | Monaco 编辑器加载 | 无 JS 错误 | ✅ | 沉淀 e2e/pages/scripts.spec.mjs |
---
## 8. 执行看板 Executions `#/executions`
| ID | 层 | 用例 | 期望 | 状态 | 实现 |
|----|-----|------|------|------|------|
| UT-EXEC-001 | UT | 进度分组 | 按 server 聚合 | ✅ | test_exec_detail_grouping.py |
| UT-EXEC-002 | UT | MySQL 持久化字段 | 状态机 | ✅ | test_script_execution_mysql_persist.py |
| IT-EXEC-001 | IT | GET /api/script-executions | 分页+filter | ✅ | tests/integration/test_scripts_executions.py |
| CH-EXEC-001 | CH | 创建执行→轮询→完成 | status=completed | ✅ | tests/chain/test_script_exec_flow.py |
| E2E-EXEC-001 | E2E | 看板页加载 | 表+筛选 | ✅ | e2e/pages/executions.spec.mjs |
| E2E-EXEC-002 | E2E | 展开执行详情行 | stdout/面板 | ✅ | e2e/pages/executions-detail.spec.mjs |
| MCP-EXEC-001 | MCP | 展开执行详情行 | stdout 片段 | ✅ | 沉淀 e2e/pages/executions-detail.spec.mjs |
---
## 9. 凭据 Credentials `#/credentials`
| ID | 层 | 用例 | 期望 | 状态 | 实现 |
|----|-----|------|------|------|------|
| UT-CRED-001 | UT | poller 周期 | mock clock | ✅ | test_credential_poller.py |
| IT-CRED-001 | IT | 列表不返回明文 secret | 脱敏 | ✅ | tests/integration/test_presets.py |
| E2E-CRED-001 | E2E | 凭据对话框表单校验 | 必填红框 | ✅ | e2e/pages/credentials.spec.mjs |
| MCP-CRED-001 | MCP | 新建凭据表单校验 | 必填红框 | ✅ | 沉淀 e2e/pages/credentials.spec.mjs |
---
## 10. 调度 Schedules `#/schedules`
| ID | 层 | 用例 | 期望 | 状态 | 实现 |
|----|-----|------|------|------|------|
| UT-SCH-001 | UT | next_run 计算 | cron/周期 | ✅ | test_schedule_next_run.py |
| UT-SCH-002 | UT | cycle 标签 | 仅开始周期 | ✅ | test_schedule_cycle.py |
| UT-SCH-003 | UT | runner once | 不重复触发 | ✅ | test_schedule_runner_once.py |
| IT-SCH-001 | IT | CRUD schedules | 审计 | ✅ | tests/integration/test_schedules.py |
| E2E-SCH-001 | E2E | 新建调度对话框 | ✅ | full-acceptance #9 |
| E2E-SCH-002 | E2E | 新建调度周期中文 | 开始执行周期 | ✅ | e2e/pages/schedules-cycle.spec.mjs |
| MCP-SCH-001 | MCP | 周期字段中文标签 | 与后端一致 | ✅ | 沉淀 E2E-SCH-002 |
---
## 11. 重试 Retries `#/retries`
| ID | 层 | 用例 | 期望 | 状态 | 实现 |
|----|-----|------|------|------|------|
| UT-RET-001 | UT | runner outcome | 成功/失败计数 | ✅ | test_retry_runner_outcome.py |
| IT-RET-001 | IT | GET /api/retries | 队列列表 | ✅ | tests/integration/test_retries_commands.py |
| E2E-RET-001 | E2E | 重试页无行级重试按钮(空表) | 表+筛选 | ✅ | e2e/pages/retries.spec.mjs |
| MCP-RET-001 | MCP | 手动重试按钮 disabled 态 | 无选中时 | ✅ | 沉淀 e2e/pages/retries.spec.mjs |
---
## 12. 命令日志 Commands `#/commands`
| ID | 层 | 用例 | 期望 | 状态 | 实现 |
|----|-----|------|------|------|------|
| IT-CMD-001 | IT | 命令/推送/会话三视图 API | 200 | ✅ | tests/integration/test_retries_commands.py |
| E2E-CMD-001 | E2E | 切换三视图 | ✅ | full-acceptance #11 |
| E2E-CMD-002 | E2E | 推送日志时间格式 | 无裸 ISO UTC | ✅ | e2e/pages/commands-time.spec.mjs |
| MCP-CMD-001 | MCP | 推送日志表北京时间 | 列格式 | ✅ | 沉淀 E2E-CMD-002 |
---
## 13. 告警 Alerts `#/alerts`
| ID | 层 | 用例 | 期望 | 状态 | 实现 |
|----|-----|------|------|------|------|
| UT-ALT-001 | UT | Agent 恢复去重 | 同 metric 1 条 | ✅ | test_agent_recovery_dedup.py |
| UT-ALT-002 | UT | Telegram 时间格式 | 北京时间 | ✅ | test_telegram_time_format.py |
| IT-ALT-001 | IT | GET /api/alerts + WS | 推送事件 | ✅ | tests/integration/test_alerts_audit.py |
| CH-ALT-001 | CH | 心跳告警→恢复→TG 一条 | Redis+mock TG | ✅ | tests/chain/test_alert_recovery_flow.py |
| E2E-ALT-001 | E2E | 告警筛选 UI | ✅ | full-acceptance #12 |
| E2E-ALT-002 | E2E | 告警表时间格式 | 无裸 ISO UTC | ✅ | e2e/pages/alerts-time.spec.mjs |
| MCP-ALT-001 | MCP | 告警表时间列 | 无 UTC 裸字符串 | ✅ | 沉淀 E2E-ALT-002 |
---
## 14. 审计 Audit `#/audit`
| ID | 层 | 用例 | 期望 | 状态 | 实现 |
|----|-----|------|------|------|------|
| IT-AUD-001 | IT | GET /api/audit 分页 | CUD 记录 | ✅ | tests/integration/test_alerts_audit.py |
| E2E-AUD-001 | E2E | 审计页+分页 | ✅ | full-acceptance #13 |
| E2E-AUD-002 | E2E | 审计表时间格式 | 无裸 ISO UTC | ✅ | e2e/pages/audit-time.spec.mjs |
| MCP-AUD-001 | MCP | 时间列北京时间 | 与设置无关 | ✅ | 沉淀 E2E-AUD-002 |
---
## 15. 设置 Settings `#/settings`
| ID | 层 | 用例 | 期望 | 状态 | 实现 |
|----|-----|------|------|------|------|
| UT-SET-001 | UT | Telegram 设置校验 | token 格式 | ✅ | test_settings_telegram.py |
| IT-SET-001 | IT | PATCH settings 禁止覆盖密钥 | 403 | ✅ | tests/integration/test_settings_security.py |
| E2E-SET-001 | E2E | 各 section 可见 | ✅ | e2e/pages/settings.spec.mjs + full-acceptance #14 |
| MCP-SET-001 | MCP | 保存设置 toast | 成功中文 | ✅ | e2e/pages/settings.spec.mjs E2E-SET-002 |
---
## 16. Agent 子机(无 SPA 页)
| ID | 层 | 用例 | 期望 | 状态 | 实现 |
|----|-----|------|------|------|------|
| UT-AGT-001 | UT | heartbeat TTL | Redis 过期 | ✅ | test_agent_heartbeat_ttl.py |
| UT-AGT-002 | UT | per-server API key | 隔离 | ✅ | test_agent_per_server_key.py |
| UT-AGT-003 | UT | version 上报 | 语义化版本 | ✅ | test_agent_version.py |
| IT-AGT-001 | IT | POST /api/agent/heartbeat | 200 | ✅ | tests/integration/test_agent_heartbeat.py |
| CH-AGT-001 | CH | 心跳→Redis→仪表盘计数 | 一致 | ✅ | tests/chain/test_agent_dashboard_flow.py |
---
## 17. 批量 / 后台任务
| ID | 层 | 用例 | 期望 | 状态 | 实现 |
|----|-----|------|------|------|------|
| UT-BAT-001 | UT | batch job 持久化 | ✅ | test_server_batch_job_persist.py |
| UT-BAT-002 | UT | reconcile 状态机 | ✅ | test_server_batch_reconcile.py |
| UT-SYNC-001 | UT | sync_log purge | ✅ | test_sync_log_purge.py |
| CH-BAT-001 | CH | 批量操作→job 表→完成 | ✅ | tests/chain/test_batch_job_flow.py |
---
## 覆盖率汇总(2026-06-08 估算)
| 层 | 已有 | 待写 | 合计 |
|----|------|------|------|
| UT | ~45 | ~15 | ~60 |
| IT | ~26 | ~11 | ~37 |
| CH | ~9 | ~5 | ~14 |
| E2E | ~35 | ~2 | ~37 |
| MCP | ~18(沉淀 E2E | ~3manual/安装) | ~21 |
| **合计** | **~133** | **~36** | **~169** |
---
## PR 检查清单
- [ ] 改动域在表中至少更新 1 行状态
- [ ] 新 API 必有 `IT-*`;新纯函数必有 `UT-*`
- [ ] UI 行为变更必有 `E2E-*``MCP-*` 计划
- [ ] 破坏性 E2E 仅对测试子机