testing
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseLobeChat Testing Guide
LobeChat 测试指南
Quick Reference
快速参考
Commands:
bash
undefined命令:
bash
undefinedRun specific test file
运行指定测试文件
bunx vitest run --silent='passed-only' '[file-path]'
bunx vitest run --silent='passed-only' '[file-path]'
Database package (client)
数据库包(客户端)
cd packages/database && bunx vitest run --silent='passed-only' '[file]'
cd packages/database && bunx vitest run --silent='passed-only' '[file]'
Database package (server)
数据库包(服务端)
cd packages/database && TEST_SERVER_DB=1 bunx vitest run --silent='passed-only' '[file]'
**Never run** `bun run test` - it runs all 3000+ tests (~10 minutes).cd packages/database && TEST_SERVER_DB=1 bunx vitest run --silent='passed-only' '[file]'
**切勿运行** `bun run test` - 它会运行全部3000+个测试(约10分钟)。Test Categories
测试分类
| Category | Location | Config |
|---|---|---|
| Webapp | | |
| Packages | | |
| Desktop | | |
| 分类 | 位置 | 配置 |
|---|---|---|
| Web应用 | | |
| 包 | | |
| 桌面端 | | |
Core Principles
核心原则
- Prefer over
vi.spyOn- More targeted, easier to maintainvi.mock - Tests must pass type check - Run after writing tests
bun run type-check - After 1-2 failed fix attempts, stop and ask for help
- Test behavior, not implementation details
- 优先使用而非
vi.spyOn- 更具针对性,更易维护vi.mock - 测试必须通过类型检查 - 编写测试后运行
bun run type-check - 经过1-2次修复尝试仍失败时,停止并寻求帮助
- 测试行为,而非实现细节
Basic Test Structure
基础测试结构
typescript
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
beforeEach(() => {
vi.clearAllMocks();
});
afterEach(() => {
vi.restoreAllMocks();
});
describe('ModuleName', () => {
describe('functionName', () => {
it('should handle normal case', () => {
// Arrange → Act → Assert
});
});
});typescript
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
beforeEach(() => {
vi.clearAllMocks();
});
afterEach(() => {
vi.restoreAllMocks();
});
describe('ModuleName', () => {
describe('functionName', () => {
it('should handle normal case', () => {
// 准备 → 执行 → 断言
});
});
});Mock Patterns
Mock模式
typescript
// ✅ Spy on direct dependencies
vi.spyOn(messageService, 'createMessage').mockResolvedValue('id');
// ✅ Use vi.stubGlobal for browser APIs
vi.stubGlobal('Image', mockImage);
vi.spyOn(URL, 'createObjectURL').mockReturnValue('blob:mock');
// ❌ Avoid mocking entire modules globally
vi.mock('@/services/chat'); // Too broadtypescript
// ✅ 监视直接依赖
vi.spyOn(messageService, 'createMessage').mockResolvedValue('id');
// ✅ 为浏览器API使用vi.stubGlobal
vi.stubGlobal('Image', mockImage);
vi.spyOn(URL, 'createObjectURL').mockReturnValue('blob:mock');
// ❌ 避免全局模拟整个模块
vi.mock('@/services/chat'); // 范围过广Detailed Guides
详细指南
See for specific testing scenarios:
references/- Database Model testing:
references/db-model-test.md - Electron IPC testing:
references/electron-ipc-test.md - Zustand Store Action testing:
references/zustand-store-action-test.md - Agent Runtime E2E testing:
references/agent-runtime-e2e.md - Desktop Controller testing:
references/desktop-controller-test.md
请查看获取特定测试场景的内容:
references/- 数据库模型测试:
references/db-model-test.md - Electron IPC测试:
references/electron-ipc-test.md - Zustand Store Action测试:
references/zustand-store-action-test.md - Agent Runtime端到端测试:
references/agent-runtime-e2e.md - 桌面端控制器测试:
references/desktop-controller-test.md
Common Issues
常见问题
- Module pollution: Use when tests fail mysteriously
vi.resetModules() - Mock not working: Check setup position and use in beforeEach
vi.clearAllMocks() - Test data pollution: Clean database state in beforeEach/afterEach
- Async issues: Wrap state changes in for React hooks
act()
- 模块污染:当测试出现莫名失败时,使用
vi.resetModules() - Mock不生效:检查设置位置,并在beforeEach中使用
vi.clearAllMocks() - 测试数据污染:在beforeEach/afterEach中清理数据库状态
- 异步问题:为React钩子的状态变化包裹
act()