TypeScript 与 Docker 集成测试:高级水平

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

TypeScript 与 Docker 集成测试:高级水平

\n\n

集成测试是验证系统组件之间交互的关键环节。对于 TypeScript 应用,尤其是微服务架构,Docker 成为不可或缺的工具。在本文中,我们将探讨使用 Docker 配置和执行集成测试的高级技术,这些技术将帮助您提高开发的可靠性和速度。

\n\n

1. 为什么在 TypeScript 集成测试中使用 Docker?

\n

Docker 可以隔离测试环境,确保其可重复性。您无需手动配置数据库、消息队列和其他依赖项,只需在容器中运行它们。这对于 TypeScript 项目尤为重要,因为类型系统可能会隐藏运行时错误,而这些错误往往在集成时才会暴露。

\n
    \n
  • 隔离性:每个测试在干净的环境中运行
  • \n
  • 速度:容器在几秒钟内启动
  • \n
  • 并行性:可以同时测试不同版本的依赖项
  • \n
\n\n

2. 为测试环境配置 Docker Compose

\n

创建一个 docker-compose.test.yml 文件,用于启动 PostgreSQL、Redis 以及测试用的应用本身:

\n
version: '3.8'\nservices:\n  db-test:\n    image: postgres:15-alpine\n    environment:\n      POSTGRES_DB: testdb\n      POSTGRES_USER: test\n      POSTGRES_PASSWORD: testpass\n    ports:\n      - "5433:5432"\n    tmpfs: /var/lib/postgresql/data\n\n  redis-test:\n    image: redis:7-alpine\n    ports:\n      - "6380:6379"\n\n  app-test:\n    build:\n      context: .\n      dockerfile: Dockerfile.test\n    environment:\n      DATABASE_URL: postgres://test:testpass@db-test:5432/testdb\n      REDIS_URL: redis://redis-test:6379\n    depends_on:\n      - db-test\n      - redis-test\n    command: ["npm", "run", "test:integration"]
\n

这里我们对数据库使用了 tmpfs,这样数据不会在每次运行之间保留,从而加快测试速度。

\n\n

3. 使用 TestContainers 进行高级 TypeScript 测试配置

\n

testcontainers 库允许您直接从 TypeScript 代码中管理容器。这提供了灵活性:您可以仅为特定的测试场景启动容器。

\n

安装:

\n
npm install --save-dev testcontainers
\n

使用动态容器的集成测试示例:

\n
import { GenericContainer, StartedTestContainer } from 'testcontainers';\nimport { Client } from 'pg';\nimport { UserService } from './user-service';\n\nlet container: StartedTestContainer;\nlet client: Client;\n\nbeforeAll(async () => {\n  // 启动 PostgreSQL 容器\n  container = await new GenericContainer('postgres:15-alpine')\n    .withEnvironment({\n      POSTGRES_DB: 'test',\n      POSTGRES_USER: 'test',\n      POSTGRES_PASSWORD: 'test'\n    })\n    .withExposedPorts(5432)\n    .start();\n\n  // 连接到测试数据库\n  const host = container.getHost();\n  const port = container.getMappedPort(5432);\n  client = new Client({\n    host,\n    port,\n    database: 'test',\n    user: 'test',\n    password: 'test'\n  });\n  await client.connect();\n\n  // 执行迁移\n  await client.query(`\n    CREATE TABLE users (\n      id SERIAL PRIMARY KEY,\n      email VARCHAR(255) UNIQUE NOT NULL,\n      name VARCHAR(255)\n    )\n  `);\n});\n\nafterAll(async () => {\n  await client.end();\n  await container.stop();\n});\n\ntest('UserService.createUser 在数据库中创建用户', async () => {\n  const userService = new UserService(client);\n  const user = await userService.createUser({\n    email: 'test@example.com',\n    name: 'Test User'\n  });\n\n  const result = await client.query('SELECT * FROM users WHERE email = $1', ['test@example.com']);\n  expect(result.rows[0]).toMatchObject({\n    email: 'test@example.com',\n                

博客

书籍推荐