267 lines
7.0 KiB
Markdown
267 lines
7.0 KiB
Markdown
# 测试文档
|
||
|
||
## 📁 测试结构
|
||
|
||
```
|
||
tests/
|
||
├── setup.ts # 测试环境初始化
|
||
├── helpers/ # 测试工具函数
|
||
│ └── mount.ts # Vue组件挂载辅助函数
|
||
├── fixtures/ # 测试数据工厂
|
||
│ ├── tasks.ts # 任务数据生成器
|
||
│ └── columns.ts # 列配置生成器
|
||
├── unit/ # 单元测试
|
||
│ └── composables/
|
||
│ └── taskRow/
|
||
│ ├── useTaskRowState.spec.ts
|
||
│ ├── useTaskRowEventHandlers.spec.ts
|
||
│ └── useTaskRowContextMenu.spec.ts
|
||
└── component/ # 组件测试
|
||
└── TaskRow.spec.ts
|
||
```
|
||
|
||
## 🎯 测试覆盖范围
|
||
|
||
### 单元测试 (Unit Tests)
|
||
|
||
#### useTaskRowState.spec.ts
|
||
测试任务行状态管理逻辑:
|
||
- ✅ 缩进计算(基于层级)
|
||
- ✅ 任务类型判断(普通/父任务/Story/里程碑)
|
||
- ✅ 进度状态(warning/success/danger)
|
||
- ✅ 超时判断(实际工时 vs 预计工时)
|
||
- ✅ 逾期天数计算
|
||
- ✅ 自定义行类名(字符串/函数)
|
||
- ✅ 自定义行样式(对象/函数)
|
||
|
||
#### useTaskRowEventHandlers.spec.ts
|
||
测试事件处理逻辑:
|
||
- ✅ 折叠/展开事件
|
||
- ✅ 行点击事件(父任务自动折叠)
|
||
- ✅ 双击事件
|
||
- ✅ 鼠标悬停事件(进入/离开)
|
||
- ✅ Splitter拖拽状态管理
|
||
- ✅ 任务行拖拽(enableDrag控制)
|
||
|
||
#### useTaskRowContextMenu.spec.ts
|
||
测试右键菜单和计时器:
|
||
- ✅ 右键菜单显示/隐藏
|
||
- ✅ 菜单位置计算
|
||
- ✅ 删除任务事件
|
||
- ✅ 计时器格式化(HH:MM:SS)
|
||
- ✅ 计时器实时更新(运行中)
|
||
- ✅ 计时器停止后显示累计时间
|
||
- ✅ 组件卸载时清理资源
|
||
|
||
### 组件测试 (Component Tests)
|
||
|
||
#### TaskRow.spec.ts
|
||
测试 TaskRow 组件:
|
||
- ✅ 基础渲染(任务名称、进度)
|
||
- ✅ 缩进应用(根据层级)
|
||
- ✅ 折叠按钮显示/隐藏
|
||
- ✅ 悬停高亮效果
|
||
- ✅ 双击事件触发
|
||
- ✅ 右键菜单功能
|
||
- ✅ 自定义样式(类名/样式对象/函数)
|
||
- ✅ 列渲染(可见性控制)
|
||
- ✅ 自定义插槽内容
|
||
- ✅ 声明式列渲染模式
|
||
|
||
## 🚀 运行测试
|
||
|
||
### 基本命令
|
||
|
||
```bash
|
||
# 运行所有测试(watch 模式)
|
||
npm run test
|
||
|
||
# 运行所有测试(单次运行)
|
||
npm run test:run
|
||
|
||
# 打开测试 UI 界面
|
||
npm run test:ui
|
||
|
||
# 生成覆盖率报告
|
||
npm run test:coverage
|
||
```
|
||
|
||
### 运行特定测试
|
||
|
||
```bash
|
||
# 运行单个测试文件
|
||
npx vitest tests/unit/composables/taskRow/useTaskRowState.spec.ts
|
||
|
||
# 运行匹配模式的测试
|
||
npx vitest --grep "计时器"
|
||
|
||
# 运行特定目录的测试
|
||
npx vitest tests/unit/
|
||
```
|
||
|
||
## 📊 覆盖率目标
|
||
|
||
| 指标 | 目标 | 说明 |
|
||
|------|------|------|
|
||
| Statements | ≥ 80% | 语句覆盖率 |
|
||
| Branches | ≥ 75% | 分支覆盖率 |
|
||
| Functions | ≥ 80% | 函数覆盖率 |
|
||
| Lines | ≥ 80% | 行覆盖率 |
|
||
|
||
查看覆盖率报告:
|
||
```bash
|
||
npm run test:coverage
|
||
# 报告生成在 coverage/ 目录
|
||
# 打开 coverage/index.html 查看详细报告
|
||
```
|
||
|
||
## 🔧 测试工具
|
||
|
||
### Fixtures (测试数据工厂)
|
||
|
||
#### tasks.ts
|
||
提供10种预配置的任务数据生成器:
|
||
- `createTask()` - 基础任务
|
||
- `createParentTask()` - 父任务(带子任务)
|
||
- `createChildTask()` - 子任务
|
||
- `createMilestone()` - 里程碑任务
|
||
- `createTaskWithPredecessor()` - 带前置任务
|
||
- `createTimerTask()` - 正在计时的任务
|
||
- `createOvertimeTask()` - 超时任务
|
||
- `createOverdueTask()` - 逾期任务
|
||
- `createReadonlyTask()` - 只读任务
|
||
- `createCustomTask()` - 自定义属性任务
|
||
|
||
示例:
|
||
```typescript
|
||
import { createTask, createParentTask } from 'tests/fixtures/tasks'
|
||
|
||
const task = createTask({ name: 'My Task', progress: 50 })
|
||
const parent = createParentTask({ id: 1, children: [task] })
|
||
```
|
||
|
||
#### columns.ts
|
||
提供列配置生成器:
|
||
- `createNameColumn()` - 名称列
|
||
- `createPredecessorColumn()` - 前置任务列
|
||
- `createAssigneeColumn()` - 负责人列
|
||
- `createStartDateColumn()` - 开始日期列
|
||
- `createEndDateColumn()` - 结束日期列
|
||
- `createProgressColumn()` - 进度列
|
||
- `createDefaultColumns()` - 默认列配置列表
|
||
|
||
### Helpers (测试工具函数)
|
||
|
||
#### mount.ts
|
||
- `mountComponent()` - 挂载 Vue 组件
|
||
- `flushPromises()` - 等待所有 Promise 完成
|
||
- `sleep(ms)` - 延迟执行
|
||
- `triggerMouseEvent()` - 触发鼠标事件
|
||
- `getComputed()` - 获取组件 computed 值
|
||
- `hasClass()` - 检查元素类名
|
||
- `getStyle()` - 获取元素样式
|
||
|
||
## 📝 编写测试指南
|
||
|
||
### 1. 单元测试示例
|
||
|
||
```typescript
|
||
import { describe, it, expect } from 'vitest'
|
||
import { ref } from 'vue'
|
||
import { useTaskRowState } from '@/composables/...'
|
||
import { createTask } from '../../../fixtures/tasks'
|
||
|
||
describe('useTaskRowState', () => {
|
||
it('应该正确计算缩进', () => {
|
||
const task = ref(createTask())
|
||
const level = ref(2)
|
||
const { taskState } = useTaskRowState(task, level)
|
||
|
||
expect(taskState.value.indent).toBe('50px') // 10 + 2*20
|
||
})
|
||
})
|
||
```
|
||
|
||
### 2. 组件测试示例
|
||
|
||
```typescript
|
||
import { describe, it, expect } from 'vitest'
|
||
import { mount } from '@vue/test-utils'
|
||
import TaskRow from '@/components/TaskList/taskRow/TaskRow.vue'
|
||
import { createTask } from '../../fixtures/tasks'
|
||
import { createDefaultColumns } from '../../fixtures/columns'
|
||
|
||
describe('TaskRow', () => {
|
||
it('应该渲染任务名称', () => {
|
||
const wrapper = mount(TaskRow, {
|
||
props: {
|
||
task: createTask({ name: 'Test Task' }),
|
||
level: 0,
|
||
columns: createDefaultColumns(),
|
||
},
|
||
})
|
||
|
||
expect(wrapper.text()).toContain('Test Task')
|
||
})
|
||
})
|
||
```
|
||
|
||
## 🐛 调试测试
|
||
|
||
### 使用 Vitest UI
|
||
|
||
```bash
|
||
npm run test:ui
|
||
```
|
||
|
||
浏览器会自动打开,提供:
|
||
- 实时测试运行状态
|
||
- 测试代码高亮
|
||
- 错误堆栈追踪
|
||
- 覆盖率可视化
|
||
|
||
### 调试单个测试
|
||
|
||
在测试文件中添加 `.only`:
|
||
```typescript
|
||
it.only('应该测试某个功能', () => {
|
||
// 只运行这个测试
|
||
})
|
||
```
|
||
|
||
### 查看详细输出
|
||
|
||
```bash
|
||
npx vitest --reporter=verbose
|
||
```
|
||
|
||
## ⚠️ 常见问题
|
||
|
||
### Q: 测试失败显示 "Cannot find module '@/...'"
|
||
A: 确保 `vitest.config.ts` 中配置了正确的路径别名。
|
||
|
||
### Q: 组件测试中 slot 不显示
|
||
A: 检查 slot 语法,确保使用 `slots: { 'slot-name': () => '...' }`。
|
||
|
||
### Q: 计时器测试不稳定
|
||
A: 使用 `vi.useFakeTimers()` 和 `vi.advanceTimersByTime()` 控制时间。
|
||
|
||
### Q: 覆盖率未达标
|
||
A: 运行 `npm run test:coverage`,打开 HTML 报告查看未覆盖代码。
|
||
|
||
## 📚 参考资料
|
||
|
||
- [Vitest 官方文档](https://vitest.dev/)
|
||
- [Vue Test Utils](https://test-utils.vuejs.org/)
|
||
- [Happy DOM](https://github.com/capricorn86/happy-dom)
|
||
|
||
## 🎯 待扩展测试
|
||
|
||
以下功能建议增加测试覆盖:
|
||
- [ ] TaskRowBadges 组件(徽章显示)
|
||
- [ ] TaskRowCollapseButton 组件(折叠按钮)
|
||
- [ ] TaskRowIcon 组件(任务图标,特别是里程碑无发光效果)
|
||
- [ ] TaskRowNameContent 组件(名称内容)
|
||
- [ ] 集成测试(TaskList 整体交互)
|
||
- [ ] 快照测试(组件输出稳定性)
|