关于 testing
这是面向 DBHub 贡献者的测试技能,涵盖 Vitest 单元测试和集成测试。文档说明了命令、测试组织方式、数据库夹具,以及基于 Docker 的集成测试排错方法。
主要功能
- 01运行单元与集成测试
- 02按文件或名称筛选测试
- 03Vitest 项目与文件约定
- 04Testcontainers 连接器测试模式
- 05排查 Docker 测试故障
适用场景
- 01无需 Docker 运行 DBHub 单元测试
- 02通过集成测试检查数据库连接器
- 03使用共享测试套件添加连接器测试
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ bytebase/ dbhub --skill testing安装后在 Claude Code 中输入/testing确认已加载。
详细介绍
测试技能
此技能可帮助你在 DBHub 项目中运行、编写和排查测试。
测试命令
pnpm test # Run all tests (unit + integration)
pnpm test:unit # Unit tests only (no Docker needed)
pnpm test:watch # Interactive watch mode
pnpm test:integration # Integration tests only (requires Docker)
运行指定测试文件:
pnpm test src/connectors/__tests__/postgres.integration.test.ts
pnpm test src/utils/__tests__/allowed-keywords.test.ts
运行名称匹配指定模式的测试:
pnpm test -- --testNamePattern="PostgreSQL"
使用详细输出进行调试:
pnpm test:integration --reporter=verbose
测试架构
vitest.config.ts 中配置了两个项目:
- unit:所有
*.test.ts文件,但排除文件名中包含*integration*的文件 - integration:仅包含
*integration*.test.ts文件
因此,命名约定很重要——集成测试的文件名必须包含 integration,才能正确分类。
测试文件位置
单元测试(约 20 个文件,无需 Docker):
src/utils/__tests__/— 工具函数测试(SQL 解析、DSN 混淆、SSH 配置、允许的关键字、标识符引用、参数映射、行数限制、安全 URL、配置监视器、AWS RDS 签名器)src/tools/__tests__/— 工具处理程序测试(execute-sql、search-objects、custom-tool-handler)src/config/__tests__/— 配置测试(环境变量解析、TOML 加载)src/connectors/__tests__/— 连接器单元测试(dsn-parser、manager)src/requests/__tests__/— 请求存储测试
集成测试(约 11 个文件,需要 Docker):
src/connectors/__tests__/postgres.integration.test.tssrc/connectors/__tests__/mysql.integration.test.tssrc/connectors/__tests__/mariadb.integration.test.tssrc/connectors/__tests__/sqlserver.integration.test.tssrc/connectors/__tests__/oracle.integration.test.tssrc/connectors/__tests__/sqlite.integration.test.tssrc/connectors/__tests__/postgres-ssh.integration.test.tssrc/connectors/__tests__/multi-sqlite-sources.integration.test.tssrc/__tests__/json-rpc-integration.test.tssrc/api/__tests__/sources.integration.test.tssrc/api/__tests__/requests.integration.test.tssrc/config/__tests__/ssh-config-integration.test.ts
IntegrationTestBase
数据库连接器集成测试继承自 src/connectors/__tests__/shared/integration-test-base.ts 中的 IntegrationTestBase<TContainer>。此抽象类提供:
- 生命周期:在
beforeAll中启动容器(超时 120 秒)→ 连接 → 设置测试数据 → 运行测试 → 在afterAll中清理 - 共享测试套件:
createConnectionTests()、createSchemaTests()、createTableTests()、createSQLExecutionTests()、createStoredProcedureTests()、createCommentTests()、createErrorHandlingTests() - 标准测试数据:
users表(id、name、email、age)+orders表(id、user_id、amount)+test_schema.products
要为新的数据库连接器添加测试,请扩展此类并实现:
createContainer()— 启动 Testcontainers 实例createConnector()— 创建数据库连接器setupTestData(connector)— 填充测试表
测试夹具
位于 src/__fixtures__/:
helpers.ts— 实用工具:fixtureTomlPath()、loadFixtureConfig()、setupManagerWithFixture()toml/multi-sqlite.toml— 三个内存中的 SQLite 数据库(database_a、database_b、database_c)toml/readonly-maxrows.toml— 配置了 readonly/max_rows 工具的来源
用法:
import { setupManagerWithFixture, FIXTURES } from '../../__fixtures__/helpers.js';
const manager = await setupManagerWithFixture(FIXTURES.MULTI_SQLITE);
// ... test ...
await manager.disconnect();
模拟模式
单元测试使用 vitest 模拟:
vi.mock('../../connectors/manager.js'); // Mock ConnectorManager
vi.mocked(ConnectorManager.getCurrentConnector).mockReturnValue(mockConnector);
SSH 隧道测试会模拟 SSHTunnel.prototype.establish,避免建立真实的 SSH 连接,同时测试配置传递。
集成测试
集成测试使用 Testcontainers 在 Docker 中运行真实的数据库实例。
前置条件
运行集成测试前:
- 已安装并运行 Docker:
docker ps - Docker 有足够的内存(建议至少 4GB,SQL Server 尤其如此)
- 可以联网拉取 Docker 镜像
数据库镜像
| 数据库 | 镜像 | 备注 |
|---|---|---|
| PostgreSQL | postgres:15-alpine | 启动速度快 |
| MySQL | @testcontainers/mysql | 支持 IAM 身份验证测试 |
| MariaDB | @testcontainers/mariadb | 支持 IAM 身份验证测试 |
| SQL Server | @testcontainers/mssqlserver | 启动较慢(3-5 分钟),需要 4GB 以上内存 |
| Oracle | @testcontainers/oraclefree (gvenzl/oracle-free:23-slim-faststart) | 拉取约需 1.2GB,启动需 1-2 分钟,需要 2GB 以上内存 |
| SQLite | 无需容器 | 内存或基于文件 |
故障排除
容器启动失败
docker ps # Verify Docker is running
docker system df # Check disk space
docker pull postgres:15-alpine # Manually pull images
SQL Server 超时
SQL Server 容器启动最慢(3-5 分钟)。请单独运行,并确保 Docker 有 4GB 以上内存:
pnpm test src/connectors/__tests__/sqlserver.integration.test.ts
测试隔离问题
每个集成测试都会管理自己的容器生命周期。如果容器未能清理,请执行:
docker ps -a | grep testcontainers # Find leaked containers
docker container prune # Clean up stopped containers
afterAll 中出现 "Hook timed out in 10000ms"
所有测试均通过,但测试套件在其 afterAll 阶段被标记为失败(在 CI 中见于 MariaDB 和
postgres-ssh)。清理操作是 container.stop(),它会依次执行 docker stop -t 0
和 docker rm -v(移除数据卷)。在共享 Docker 守护进程同时拉取或解压 Oracle 或 SQL Server 镜像时,移除操作可能
会超过 Vitest 默认的 10 秒钩子超时时间。因此,集成项目在 vitest.config.ts 中设置了
hookTimeout: 60_000——请勿为 afterAll 指定更短的
超时时间;如果添加带有自身清理操作的测试套件,请使用项目默认值,而非 Vitest 默认值。
CI 失败
CI 工作流(.github/workflows/run-tests.yml)会在 PR 事件中将单元测试和集成测试作为两个并行作业运行。单元测试不需要 Docker;集成测试会先验证 Docker 是否可用。请检查具体失败的作业。
添加新测试
单元测试:创建 src/{module}/__tests__/{name}.test.ts——它会在运行 pnpm test:unit 时自动执行。
集成测试:创建 src/{module}/__tests__/{name}.integration.test.ts——文件名中的 integration 会将其路由到 pnpm test:integration。
新连接器测试:扩展 IntegrationTestBase,实现三个抽象方法,并调用共享测试套件的方法。