Appearance
测试策略
测试金字塔
原则: 纯函数优先单元测试;Store/Composable/组件交互用集成测试;跨页面流程用人工验证。
MVP 阶段不使用 E2E 测试。
单元测试
位置: test/unit/命名: {模块名}.test.ts适用范围: 零框架依赖的纯函数(shared/utils/edge-validation.ts、数据转换、算法逻辑)
typescript
it('在存在 A→B 边时,添加 B→A 边应检测为循环', () => {
// Arrange
const edges = [{ source: 'a', target: 'b' }]
const newEdge = { source: 'b', target: 'a' }
// Act
const result = validateEdge(edges, newEdge)
// Assert
expect(result).toEqual({ valid: false, reason: 'cycle' })
})集成测试
位置: test/nuxt/命名: {模块名}.test.ts适用范围: Pinia Store、Composable、依赖真实 DOM 的组件逻辑 运行命令: pnpm test:nuxt
Store 测试模式:
typescript
beforeEach(() => {
setActivePinia(createPinia())
})BDD 场景验证方式
Spec 中的 BDD 场景根据类型分配验证方式:
| BDD 场景类型 | 验证方式 | 示例 |
|---|---|---|
| 纯数据流 | 单元测试 | 边校验、上游收集、状态机转换 |
| 组件交互 | Nuxt 集成测试 | 节点选中切换模式、生成按钮、模型选择 |
| 跨页面流程 | 人工验证 checklist | 创建画布→编辑→返回列表 |
BDD Scenario 到集成测试的映射:
typescript
// test/nuxt/canvas-system.test.ts
it('从工具栏添加节点后节点出现在画布中', async () => {
// Given: 画布编辑器已挂载
const component = await mountSuspended(CanvasEditor, { /* ... */ })
// When: 触发添加文本节点
await component.find('[data-testid="toolbar-add"]').trigger('click')
await component.find('[data-testid="node-type-text"]').trigger('click')
// Then: 画布中出现文本节点
expect(component.find('[data-testid="node-text"]').exists()).toBe(true)
})人工验证 checklist(发版前执行)
| 场景 | 优先级 | 对应 Spec |
|---|---|---|
| 创建画布 → 添加节点 → 连线 → 生成 | P0 | canvas-system + node-shell |
| Workspace CRUD → 导航到画布 | P0 | workspace |
| 刷新页面后画布数据恢复 | P0 | canvas-system |
| 文本节点:富文本格式化 → 生成 → 结果填充编辑器 | P0 | text-node |
| 图片节点:上传图片 → 带参考图生成 → 多变体选择 | P0 | image-node |
| 视频节点:上传视频 → 播放控制 → 生成替换 | P0 | video-node |
| 节点选中/取消选中 → 悬浮面板出现/消失 | P1 | node-shell |
| 右键菜单 → 删除节点 | P1 | node-shell |
| 多选节点 → group handle → 批量连线 | P1 | batch-connect |
| 上游连线变更后缩略图预览实时更新 | P1 | data-flow |
| 连线方向/拓扑/角色校验 → 非法连线阻止 | P1 | edge-system |
升级规则:当某个手动场景反复出现回归 bug 时,针对性补充集成测试。
data-testid 规范
所有可交互的 UI 元素必须挂载 data-testid:
| 组件 | data-testid |
|---|---|
| 工具栏添加按钮 | toolbar-add |
| 节点类型选项 | node-type-{text|image|video} |
| 节点卡片 | node-{type} |
| 生成按钮 | node-generate |
| Prompt 输入 | node-prompt |
| 节点状态指示 | node-status-{idle|generating|done|error} |
覆盖率目标
| 层级 | 目标 | 重点 |
|---|---|---|
| 单元 | > 90% | flowValidation、数据转换函数 |
| 集成 | > 70% | Store 所有 public action |
| 人工 checklist | 发版前 100% 执行 | P0 跨页面场景不遗漏 |
覆盖率度量方式:
- 自动化覆盖率 = Vitest coverage(
pnpm test -- --coverage),合并单元 + 集成 - 手动覆盖率 = 上方人工验证 checklist 完成度
运行命令
bash
pnpm test # 全量测试(单元 + 集成)
pnpm test:unit # 仅单元测试
pnpm test:nuxt # 仅集成测试
pnpm test:unit --watch # 开发时持续运行