使用 Docker 进行 JavaScript 集成测试:高级技术

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

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

开始课程

使用 Docker 进行 JavaScript 集成测试:从理论到高级实践

\n\n

集成测试是开发中至关重要的阶段,它检查不同模块与外部服务之间的交互。对于基于 Node.js 的 JavaScript 应用程序,Docker 成为不可或缺的工具,它能够创建隔离、可重现的测试环境。在本文中,我们将探讨使用 Docker 配置集成测试的高级技术,包括与数据库、队列的协作以及针对 CI/CD 的优化。

\n\n

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

\n\n

传统的集成测试方法(mocks, stubs)并不总能反映系统的真实行为。Docker 通过提供以下功能解决了这个问题:

\n\n
    \n
  • 隔离性:每个测试在干净的容器中运行,不会影响其他测试或本地环境。
  • \n
  • 可重现性:在开发机器和 CI/CD 中具有相同的执行条件。
  • \n
  • 可扩展性:能够并行运行具有不同依赖版本(PostgreSQL, Redis, Elasticsearch)的测试。
  • \n
  • 快速恢复:重新创建容器只需几秒钟,而不是数小时的配置时间。
  • \n
\n\n

配置高级测试环境

\n\n

考虑一个典型的 Node.js 应用程序,它使用 PostgreSQL 和 Redis。我们将创建一个灵活的配置,支持并行测试和健康检查,而不是简单的 docker-compose.yml。

\n\n

步骤 1:使用动态端口的 Docker Compose

\n\n

为了避免并行运行时出现端口冲突,我们使用动态分配:

\n\n
# docker-compose.test.yml\nversion: '3.8'\nservices:\n  postgres_test:\n    image: postgres:15-alpine\n    environment:\n      POSTGRES_DB: test_db\n      POSTGRES_USER: test_user\n      POSTGRES_PASSWORD: test_pass\n    ports:\n      - "0:5432"  # 动态端口\n    healthcheck:\n      test: ["CMD-SHELL", "pg_isready -U test_user -d test_db"]\n      interval: 2s\n      timeout: 5s\n      retries: 10\n    tmpfs: /var/lib/postgresql/data  # 数据存储在 RAM 中以加快速度\n\n  redis_test:\n    image: redis:7-alpine\n    ports:\n      - "0:6379"\n    healthcheck:\n      test: ["CMD", "redis-cli", "ping"]\n      interval: 2s\n      timeout: 5s\n      retries: 10
\n\n

步骤 2:用于 Docker 测试的实用工具

\n\n

创建一个辅助类,自动查找动态端口并等待服务就绪:

\n\n
// test/setup/docker-manager.js\nconst { DockerComposeEnvironment, Wait } = require('testcontainers');\nconst { Client } = require('pg');\nconst Redis = require('ioredis');\n\nclass DockerTestManager {\n    constructor() {\n        this.environment = null;\n        this.config = {\n            pgPort: null,\n            redisPort: null\n        };\n    }\n\n    async start() {\n        this.environment = await new DockerComposeEnvironment(\n            '.', \n            'docker-compose.test.yml'\n        ).withWaitStrategy('postgres_test', Wait.forHealthCheck())\n         .withWaitStrategy('redis_test', Wait.forHealthCheck())\n         .up();\n\n        // 提取端口映射\n        const pgContainer = this.environment.getContainer('postgres_test');\n        const redisContainer = this.environment.getContainer('redis_test');\n        \n        this.config.pgPort = pgContainer.getMappedPort(5432);\n        this.config.redisPort = redisContainer.getMappedPort(6379);\n        \n        return this.config;\n    }\n\n    async stop() {\n        if (this.environment) {\n            await this.environment.down();\n        }\n    }\n}\n\nmodule.exports = DockerTestManager;
\n\n

高级集成测试场景

\n\n

现在,让我们转向具体的测试,这些测试检查组件之间的真实交互。

\n

博客

书籍推荐