# Testing Guide ## Test layers 项目当前采用四层测试结构: ### 1. 静态检查 - `pnpm check` - `pnpm build` - `go build ./...` 用于保证类型、打包和 Go 媒体服务编译可通过。 ### 2. 单元测试 - `pnpm test` 当前覆盖: - Node/tRPC 路由输入校验与权限检查 - 实时分析会话保存、管理员权限与异步 NTRP 刷新入队 - LLM 模块请求配置与环境变量回退逻辑 - 视觉模型 per-request model override 能力 - 视觉标准图库路由与 admin/H1 全量可见性逻辑 - 媒体工具函数,例如录制时长格式化与码率选择 - 实时分析动作片段保存、成就回写和 NTRP 刷新入队逻辑 ### 3. Go 媒体服务测试 - `pnpm test:go` 当前覆盖: - `media/health` - 会话创建与状态聚合 - 归档流程的基础回放产物生成 ### 4. 浏览器 E2E - `pnpm test:e2e` 使用 Playwright。为保证稳定性: - 启动本地测试服务器 `pnpm dev:test` - 测试服务器启动前要求数据库已完成 Drizzle 迁移 - 通过路由拦截模拟 tRPC 和 `/media` 接口 - 注入假媒体设备、假 `MediaRecorder` 和假 `RTCPeerConnection` 这样可以自动验证前端主流程,而不依赖真实摄像头权限和真实 WebRTC 网络环境。 当前 E2E 已覆盖新的后台任务流、实时分析入口、录制焦点视图和任务中心依赖的接口 mock。 当前 E2E 还覆盖视频库轻剪辑工作台,包括建议片段渲染、轻剪辑入口和草稿导出入口。 首次在新库或新 schema 上执行前,先跑: ```bash set -a && source .env && set +a && pnpm exec drizzle-kit migrate ``` ## Unified verification 一次性执行全部自动验证: ```bash pnpm verify ``` 执行顺序: 1. `pnpm check` 2. `pnpm test` 3. `pnpm test:go` 4. `pnpm build` 5. `pnpm test:e2e` ## Live LLM smoke test 使用真实 LLM 网关验证当前 `.env` 中的配置: ```bash pnpm test:llm pnpm test:llm -- "你好,做个自我介绍" ``` 说明: - 该命令会直接请求 `LLM_API_URL` - 适合验证 `LLM_API_KEY`、`LLM_MODEL` 和网关连通性 - 不建议纳入 `pnpm verify`,因为它依赖外部网络和真实密钥 多模态链路建议额外执行一次手工 smoke test: ```bash pnpm exec tsx -e 'import "dotenv/config"; import { invokeLLM } from "./server/_core/llm"; const result = await invokeLLM({ model: process.env.LLM_VISION_MODEL, apiUrl: process.env.LLM_VISION_API_URL, apiKey: process.env.LLM_VISION_API_KEY, messages: [{ role: "user", content: [{ type: "text", text: "请用中文一句话描述图片" }, { type: "image_url", image_url: { url: "https://..." } }] }] }); console.log(result.model, result.choices[0]?.message?.content);' ``` 如果返回模型与 `LLM_VISION_MODEL` 不一致,说明上游网关忽略了视觉模型选择,业务任务会自动回退到文本纠正结果。 视觉标准图库的真实 smoke test 可直接复用内置数据: - 初始化 `ADMIN_USERNAMES=H1` - 登录 `H1` 后访问 `/vision-lab` - 检查标准图是否已经入库 - 运行单张或批量测试,确认结果会写入 `vision_test_runs` - 若上游视觉网关不可用,记录应显示 `fallback` 2026-03-15 额外完成了多模态兼容与历史修复验证: - 使用真实公网网球图片调用视觉链路,确认服务端能兼容上游返回的非标准 JSON 字段 - 重跑历史 3 条 `fallback` 标准图记录,确认已全部转为 `visionStatus=ok` - Playwright 真实站点检查 `https://te.hao.work/vision-lab`,确认页面不再出现 `Cannot read properties of undefined (reading 'join')` ## Production smoke checks 部署到宿主机后,建议至少补以下联测: ```bash docker compose ps curl -I https://te.hao.work/ curl http://127.0.0.1:8081/media/health pnpm test:llm ``` 推荐再增加一轮浏览器级检查: - 打开 `https://te.hao.work/` - 打开 `https://te.hao.work/login` - 打开 `https://te.hao.work/checkin` - 打开 `https://te.hao.work/admin`(管理员) - 打开 `https://te.hao.work/recorder` - 打开 `https://te.hao.work/live-camera` - 确认没有 `pageerror` 或首屏 `console.error` 真实站点 Playwright smoke script 可直接复用: ```bash xvfb-run -a bash -lc 'cd /root/.codex/skills/playwright-skill && node run.js /tmp/playwright-te-smoke.js' ``` 2026-03-15 已实际完成一次真实环境联调: - 初次 smoke 发现 `https://te.hao.work/checkin` 仍显示旧版“每日打卡 / 训练打卡”,确认现网落后于仓库代码 - 执行 `docker compose up -d --build migrate app app-worker` 后再次 smoke - 复测 `login / checkin / videos / recorder / live-camera / admin` 全部通过,且未捕获 `pageerror` / `console.error` ## Local browser prerequisites 首次运行 Playwright 前执行: ```bash pnpm exec playwright install chromium ``` ## Notes - E2E 目前验证的是“模块主流程是否正常”,不是媒体编码质量本身 - 若需要真实录制验证,可额外用本地 Chrome 和真实摄像头做手工联调 - 若 `pnpm test:e2e` 失败,优先检查: - 本地数据库是否已执行最新 Drizzle 迁移 - `PORT=3100` 是否被占用 - 浏览器依赖是否安装 - 前端路由或测试标识是否被改动