测试文档
测试框架
项目使用 Bun 内置测试框架 (bun test),支持 TypeScript,无需额外配置。
运行测试
# 运行所有测试
bun test
# 运行特定测试文件
bun test tests/unit/storage/database.test.ts
# 监听模式(自动重新运行)
bun test --watch
# 生成覆盖率报告
bun test --coverage
测试结构
tests/
├── helpers/ # 测试辅助函数
│ ├── test-utils.ts # 通用测试工具(临时目录、环境变量等)
│ ├── database-helper.ts # 数据库测试辅助
│ └── tool-helper.ts # 工具测试辅助
├── fixtures/ # 测试数据
│ └── test-data.ts # 测试数据定义
├── unit/ # 单元测试
│ ├── storage/ # 存储层测试
│ │ ├── database.test.ts
│ │ └── config.test.ts
│ └── tools/ # 工具测试
│ ├── programming/ # 编程工具
│ ├── family/ # 家庭工具
│ ├── hobbies/ # 爱好工具
│ ├── common/ # 通用工具
│ └── devops/ # DevOps 工具
└── integration/ # 集成测试
└── mcp-server.test.ts
测试覆盖
✅ 存储层测试
- 代码片段 CRUD 操作
- 笔记 CRUD 操作
- 任务 CRUD 操作
- 数学资源 CRUD 操作
- 育儿里程碑 CRUD 操作
- 游戏愿望单 CRUD 操作
- 搜索功能
✅ 配置管理测试
- 环境变量加载
- 配置获取方法
✅ 编程工具测试
- 代码片段管理(保存、搜索、列出、删除)
- 项目模板生成(Vite+Vue3、全栈项目)
- 技术文档查询(TypeScript、Vue3、Bun)
- 代码审查和优化
✅ 家庭工具测试
- 数学资源搜索和保存
- 数学题目生成(不同年级和难度)
- 育儿里程碑记录
- 育儿提醒设置
✅ 爱好工具测试
- 游戏信息查询
- 游戏折扣查询
- 游戏愿望单管理
- 足球信息查询(mock)
✅ 通用工具测试
- 笔记创建、搜索、列出、删除
- 任务添加、列出、完成
✅ 服务器工具测试
- 服务器状态查询(mock SSH)
- 服务器日志查看(mock SSH)
- 部署功能验证
✅ 集成测试
- 工具注册验证
- 工具调用测试
- 错误处理测试
测试隔离
每个测试使用独立的临时目录和数据存储,确保测试之间不会相互影响:
beforeEach(() => {
testContext = createTempDir();
cleanupDb = setupTestDatabase(testContext);
});
afterEach(() => {
cleanupDb();
testContext.cleanup();
});
测试统计
- 总测试数: 77
- 通过: 77 ✅
- 失败: 0
- 测试文件: 14
注意事项
- NAS 和软路由测试: 由于需要隧道穿透,这些功能的测试被排除在外
- SSH 连接测试: 使用 mock,不会实际连接服务器
- API 测试: 游戏和足球 API 测试可能会因为网络问题失败,但会优雅处理
- 测试数据: 所有测试数据存储在临时目录,测试结束后自动清理
调试测试
如果测试失败,可以使用以下方法调试:
# 运行单个测试并显示详细输出
bun test tests/unit/storage/database.test.ts --reporter verbose
# 使用 Node.js 调试器
bun test --inspect
添加新测试
- 在相应的测试目录创建测试文件
- 使用
describe和test组织测试 - 使用
beforeEach和afterEach设置和清理 - 使用测试辅助函数(
callTool,setupTestDatabase等)
示例:
import { describe, test, expect, beforeEach, afterEach } from "bun:test";
import { callTool } from "../../helpers/tool-helper.js";
import { createTempDir } from "../../helpers/test-utils.js";
import { setupTestDatabase } from "../../helpers/database-helper.js";
describe("My Tool", () => {
let testContext: ReturnType<typeof createTempDir>;
let cleanupDb: () => void;
beforeEach(() => {
testContext = createTempDir();
cleanupDb = setupTestDatabase(testContext);
registerMyTool();
});
afterEach(() => {
cleanupDb();
testContext.cleanup();
});
test("should do something", async () => {
const result = await callTool("my_tool", { arg: "value" });
expect(result.content[0].text).toContain("expected");
});
});