使用 Docker 进行 JavaScript 集成测试:高级水平

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

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

开始课程

使用 Docker 进行 JavaScript 集成测试:高级水平



集成测试是现代 Web 应用程序开发的关键阶段。它允许检查系统不同组件(数据库、缓存、外部 API 和应用程序本身)之间的交互。Docker 使这个过程变得可预测、隔离且可重复。在本文中,我们将探讨使用 Docker 进行 JavaScript (Node.js) 集成测试的高级技术。



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

传统的集成测试面临以下问题:

  • 开发环境、CI 环境和生产环境之间的差异。
  • 共享数据库中的数据污染。
  • 启动依赖项(Redis、PostgreSQL、Kafka)的复杂性。

Docker 通过提供轻量级、隔离的容器解决了这些问题。每个测试都可以启动自己的基础设施,并在完成后销毁它。这保证了结果的清洁性和可重复性。



使用 Docker Compose 配置测试环境

对于高级测试,我们将使用 docker-compose.yml,它描述了测试所需的所有服务:应用程序本身、数据库、缓存和模拟服务器。



示例 docker-compose.test.yml:

version: '3.8'services:  app:    build: .    environment:      - NODE_ENV=test      - DB_HOST=postgres_test      - REDIS_HOST=redis_test      - MOCK_SERVER_URL=http://mock-server:8080    depends_on:      - postgres_test      - redis_test      - mock-server    command: ["npm", "run", "test:integration"]

postgres_test: image: postgres:15-alpine environment: POSTGRES_DB: testdb POSTGRES_USER: test POSTGRES_PASSWORD: test tmpfs: /var/lib/postgresql/data

redis_test: image: redis:7-alpine tmpfs: /data

mock-server: image: mockserver/mockserver:latest environment: MOCKSERVER_LOG_LEVEL: ERROR


关键点:

  • tmpfs:数据库和 Redis 数据存储在内存中,从而加快测试速度。
  • mock-server:用于模拟外部 API 的隔离服务。
  • NODE_ENV=test:将应用程序切换到测试配置。


使用 Testcontainers 编写集成测试

Node.js 的 testcontainers 库允许直接从测试中以编程方式管理容器。这提供了灵活性:您可以为每个测试套件启动特定的容器。



安装:

npm install --save-dev testcontainers


使用 PostgreSQL 的测试示例:

const { GenericContainer } = require('testcontainers');const { Client } = require('pg');

describe('User Repository Integration Test', () => { let container; let client;

beforeAll(async () => { // 启动 PostgreSQL 容器 container = await new GenericContainer('postgres:15-alpine') .withEnvironment({ POSTGRES_DB: 'testdb', POSTGRES_USER: 'test', POSTGRES_PASSWORD: 'test' }) .withExposedPorts(5432) .start();

// 连接到容器 client = new Client({ host: container.getHost(), port: container.getMappedPort(5432), database: 'testdb', user: 'test', password: 'test' }); await client.connect();

// 创建模式 await client.query(` CREATE TABLE users ( id SERIAL PRIMARY KEY, name VARCHAR(100), email VARCHAR(100) UNIQUE ) `); });

afterAll(async () => { await client.end(); await container.stop(); });

test('should insert and retrieve user', async () => { await client.query(

博客

书籍推荐