# 单元测试快速开始指南 ## 安装依赖 ```bash npm install -D vitest @vue/test-utils @pinia/testing happy-dom @vitest/coverage-v8 ``` ## 运行测试 ```bash # 运行所有测试(watch模式) npm run test # 运行所有测试(单次) npm run test:run # 生成覆盖率报告 npm run test:coverage # 运行UI界面 npm run test:ui ``` ## 测试文件结构 ``` tests/ ├── unit/ # 单元测试 │ ├── stores/ # Store测试 │ │ ├── player.spec.js # ✅ 已完成 │ │ └── game.spec.js # 待编写 │ └── systems/ # 系统测试 │ ├── skillSystem.spec.js # ✅ 已完成 │ ├── combatSystem.spec.js # ✅ 已完成 │ ├── itemSystem.spec.js # 待编写 │ ├── taskSystem.spec.js # 待编写 │ ├── eventSystem.spec.js # 待编写 │ ├── gameLoop.spec.js # 待编写 │ └── storage.spec.js # 待编写 ├── fixtures/ # 测试夹具 │ ├── player.js # ✅ 已完成 │ ├── game.js # ✅ 已完成 │ ├── items.js # ✅ 已完成 │ └── enemies.js # ✅ 已完成 └── helpers/ # 测试辅助函数 ├── store.js # ✅ 已完成 ├── timer.js # ✅ 已完成 └── random.js # ✅ 已完成 ``` ## 编写新测试的步骤 ### 1. 创建测试文件 在 `tests/unit/systems/` 下创建新文件,例如 `itemSystem.spec.js` ### 2. 导入必要的模块 ```javascript import { describe, it, expect, beforeEach } from 'vitest' import { createPinia, setActivePinia } from 'pinia' import { usePlayerStore } from '@/store/player.js' import { useGameStore } from '@/store/game.js' import { yourFunction } from '@/utils/itemSystem.js' import { createMockPlayer } from '../../fixtures/player.js' ``` ### 3. Mock 配置文件(如果需要) ```javascript vi.mock('@/config/items.js', () => ({ ITEM_CONFIG: { // 测试数据 } })) ``` ### 4. 编写测试用例 ```javascript describe('物品系统', () => { let playerStore let gameStore beforeEach(() => { setActivePinia(createPinia()) playerStore = usePlayerStore() gameStore = useGameStore() }) it('应该成功添加物品', () => { const result = addItemToInventory(playerStore, 'test_item', 1) expect(result.success).toBe(true) expect(playerStore.inventory.length).toBe(1) }) }) ``` ## 测试最佳实践 ### 1. 使用 AAA 模式 ```javascript it('应该正确计算价格', () => { // Arrange - 准备数据 const item = { baseValue: 100, quality: 150 } // Act - 执行操作 const price = calculatePrice(item) // Assert - 验证结果 expect(price).toBe(150) }) ``` ### 2. 测试命名清晰 ```javascript // ✅ 好的命名 it('当技能未解锁时,应拒绝添加经验', () => {}) it('升级时等级应增加1', () => {}) // ❌ 不好的命名 it('test1', () => {}) it('works', () => {}) ``` ### 3. 使用测试夹具 ```javascript import { createMockPlayer } from '../../fixtures/player.js' beforeEach(() => { Object.assign(playerStore, createMockPlayer()) }) ``` ### 4. Mock 外部依赖 ```javascript // Mock uni API global.uni = { setStorageSync: vi.fn(() => true), getStorageSync: vi.fn(() => null) } // Mock 随机数 vi.spyOn(Math, 'random').mockReturnValue(0.5) ``` ## 当前测试覆盖情况 ### ✅ 已完成 - [x] Player Store 测试 (player.spec.js) - [x] 技能系统测试 (skillSystem.spec.js) - [x] 战斗系统测试 (combatSystem.spec.js) - [x] 所有测试夹具 (fixtures/) - [x] 所有测试辅助函数 (helpers/) ### 📝 待编写 - [ ] Game Store 测试 - [ ] 物品系统测试 - [ ] 任务系统测试 - [ ] 事件系统测试 - [ ] 游戏循环测试 - [ ] 存档系统测试 - [ ] 环境系统测试 ## 查看测试覆盖率 ```bash npm run test:coverage ``` 生成的报告位于: - 终端输出:文本格式 - coverage/index.html:HTML格式(可在浏览器查看) ## 常见问题 ### Q: uni API 未定义 **A**: 已在 `tests/setup.js` 中 mock,如果还有问题,检查是否正确导入 setup 文件 ### Q: Pinia Store 测试报错 **A**: 使用 `setActivePinia(createPinia())` 初始化 ### Q: 测试超时 **A**: 在 `vitest.config.js` 中增加 `testTimeout: 10000` ### Q: Mock 不生效 **A**: 确保在测试文件顶部 mock,在导入被测试模块之前 ## 下一步工作 按优先级顺序: 1. **P0 - 核心模块** - Game Store 测试 - 存档系统测试 - 游戏循环测试 2. **P1 - 核心机制** - 物品系统测试 - 任务系统测试 3. **P2 - 辅助系统** - 事件系统测试 - 环境系统测试 参考 `TEST_PLAN.md` 获取详细的测试用例列表。