Files
jordium-gantt-vue3/tests/README.md
T

331 lines
8.9 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.
# 测试文档
## 📁 测试结构
```
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)
## 🧪 性能与算法测试
### test-interval-tree.html
区间树算法可视化测试页面,用于验证 v1.9.3 中的性能优化:
**测试内容**
-**测试1**: 算法切换验证(50/100/101/200任务)
-**测试2**: 性能对比(O(n²) vs O(n log n)
-**测试3**: 结果正确性验证
-**测试4**: 极限场景测试(500任务)
**使用方法**
```bash
# 直接在浏览器中打开
open tests/test-interval-tree.html
```
**验证目标**
- 任务数 > 100 时自动切换到区间树算法
- 500任务场景性能提升 2.8-3.5 倍(120ms → 42ms
- 算法优化不影响功能正确性
### verify-interval-tree.js
控制台验证脚本,提供4种验证方法:
**使用方法**
```bash
# 方法1: 在项目运行时,浏览器控制台执行
node tests/verify-interval-tree.js
# 方法2: 在 Demo 中查看实时监控日志
# 1. npm run dev
# 2. 切换到资源视图
# 3. 拖拽任务条
# 4. 查看控制台输出 [Conflict Detection] 日志
```
**验证检查清单**
- ☑️ src/utils/conflictUtils.ts 包含 IntervalTree 类
- ☑️ src/utils/conflictUtils.ts 包含 detectConflictsWithIntervalTree 函数
- ☑️ detectConflicts 函数有算法选择逻辑
- ☑️ perfMonitor.ts 包含 recordConflictDetection 方法
- ☑️ 性能目标: 500任务从120ms降至~40ms
### demo/data-resources-large.json
大数据集测试文件(由 `scripts/generate-large-data.js` 生成):
**数据规模**
- 100个资源
- 约2500个任务
- 任务分布:每个资源20-30个任务
**用途**
- 测试资源视图垂直滚动性能
- 验证区间树算法在大数据量下的表现
- 测试冲突检测性能(多资源场景)
**重新生成数据**
```bash
node scripts/generate-large-data.js
```
## 🎯 待扩展测试
以下功能建议增加测试覆盖:
- [ ] TaskRowBadges 组件(徽章显示)
- [ ] TaskRowCollapseButton 组件(折叠按钮)
- [ ] TaskRowIcon 组件(任务图标,特别是里程碑无发光效果)
- [ ] TaskRowNameContent 组件(名称内容)
- [ ] 集成测试(TaskList 整体交互)
- [ ] 快照测试(组件输出稳定性)
- [ ] GanttConflicts 组件测试(Canvas 渲染、冲突可视化)
- [ ] 区间树算法单元测试(正确性、边界条件)