使用 Docker 进行 TypeScript 集成测试:完整指南

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

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

开始课程

使用 Docker 进行 TypeScript 集成测试:从 A 到 Z



现代 TypeScript 开发不仅需要高质量的单元测试,还需要在真实环境中验证组件间的交互。使用 Docker 进行集成测试可以启动包含数据库、缓存和其他服务的隔离环境,使测试尽可能接近生产环境。在本文中,我们将探讨如何使用 Docker 配置 TypeScript 应用程序的集成测试,为 REST API 编写测试,并介绍最佳实践。



为什么选择 Docker 进行集成测试?



Docker 解决了集成测试的主要问题之一——对外部服务的依赖。我们不是使用可能被其他开发人员占用的公共数据库或 Redis,而是为每次测试运行启动隔离的容器。这保证了:



  • 测试的洁净性:每次运行都从空状态开始
  • 可重复性:测试在任何机器上运行结果一致
  • 隔离性:测试之间互不影响,也不影响生产数据
  • 速度:容器在几秒钟内启动


项目配置与 Docker Compose



让我们创建一个使用 Express 和 PostgreSQL 的简单 TypeScript 项目。我们的目标是测试创建用户的端点。从 docker-compose.test.yml 文件开始:



version: '3.8'services:  db_test:    image: postgres:15-alpine    environment:      POSTGRES_DB: testdb      POSTGRES_USER: testuser      POSTGRES_PASSWORD: testpass    ports:      - "5433:5432"    healthcheck:      test: ["CMD-SHELL", "pg_isready -U testuser -d testdb"]      interval: 5s      timeout: 5s      retries: 5

app_test: build: context: . dockerfile: Dockerfile.test environment: DATABASE_URL: postgres://testuser:testpass@db_test:5432/testdb NODE_ENV: test ports: - "3001:3000" depends_on: db_test: condition: service_healthy


现在创建 Dockerfile.test 来构建 TypeScript 应用程序:



FROM node:18-alpineWORKDIR /appCOPY package*.json ./RUN npm ci --only=productionCOPY . .RUN npm run buildCMD ["node", "dist/index.js"]


使用 Jest 和 Supertest 编写集成测试



安装必要的包:



npm install --save-dev jest @types/jest ts-jest supertest @types/supertest


创建 Jest 配置(jest.config.ts):



export default {  preset: 'ts-jest',  testEnvironment: 'node',  testMatch: ['**/__tests__/**/*.test.ts'],  setupFilesAfterSetup: ['./jest.setup.ts'],  testTimeout: 30000,};


jest.setup.ts 文件将负责启动和停止 Docker 容器:



import { execSync, spawn } from 'child_process';import path from 'path';

const composeFile = path.resolve(__dirname, '../docker-compose.test.yml');

beforeAll(async () => { // 启动容器 execSync(`docker-compose -f ${composeFile} up -d --build`, { stdio: 'inherit' }); // 等待应用程序可用 await new Promise((resolve) => setTimeout(resolve, 5000));});

afterAll(async () => { // 停止并删除容器 execSync(`docker-compose -f ${composeFile} down -v`, { stdio: 'inherit' });});


现在编写测试本身。创建文件 __tests__/users.test.ts:



import request from 'supertest';

const BASE_URL = 'http://localhost:3001/api';

describe('Users API Integration Tests', () => { const testUser = { name: '伊万·伊万诺夫', email: 'ivan@example.com', password: 'securePass123' };

博客

书籍推荐