Integration Testing JavaScript with Docker: From A to Z
\n\nIn modern web development, code quality is not just a metric, but the key to product stability. Integration Testing occupies a key place in the testing pyramid, allowing you to verify the interaction between different modules, databases, external APIs, and services. However, setting up isolated and reproducible environments for such tests often becomes a headache. This is where Docker comes to the rescue — a containerization tool that is ideal for creating clean, repeatable test environments.
\n\nIn this article, we will break down how to organize integration testing for JavaScript (Node.js) applications using Docker. You will learn how to spin up a test database, launch dependencies in containers, and write effective tests that can be easily integrated into a CI/CD pipeline.
\n\n1. Why is Docker ideal for integration tests?
\n\nThe traditional approach to integration testing often requires manual environment setup on each developer machine or CI server. This leads to the "it works on my machine" problem. Docker solves this problem radically:
\n\n- \n
- Isolation: Each test runs in a clean container, eliminating the influence of side effects from previous runs. \n
- Reproducibility: The same environment (Node.js version, databases, system libraries) is guaranteed to work everywhere: on the developer's local machine, on the build server, and in production. \n
- Dependency Management: You can easily spin up complex infrastructures (Redis, PostgreSQL, RabbitMQ) with a single command
docker-compose up -d. \n - Speed: Containers start in seconds, unlike virtual machines. Docker caches layers, which speeds up rebuilds. \n
In the context of Node.js, Docker allows you to "mock" external services without leaving the development environment. Instead of hitting a production API, you spin up a test container with, for example, json-server or testcontainers.
2. Setting up a Node.js project for testing
\n\nLet's assume we have a simple Express application that saves users to PostgreSQL. Our task is to test the POST /users endpoint.
Project structure:
\n\nproject/\n├── src/\n│ ├── app.js\n│ ├── db.js\n│ └── routes/\n│ └── users.js\n├── test/\n│ └── integration/\n│ └── users.test.js\n├── docker-compose.test.yml\n├── Dockerfile\n├── package.json\n└── .env.test\n\n\n
For tests, we will use a popular stack: Mocha (framework) + Chai (assertion library) + Supertest (HTTP testing).
\n\nInstall dependencies:
\nnpm install --save-dev mocha chai supertest\n\nThe package.json file should contain a script to run tests:
{\n "scripts": {\n "test:integration": "mocha test/integration/**/*.test.js --timeout 10000"\n }\n}\n\n3. Creating a Docker environment for tests
\n\nThe key file is docker-compose.test.yml. It describes the services required for the tests.
version: '3.8'\n\nservices:\n app-test:\n build:\n context: .\n dockerfile: Dockerfile\n environment:\n - NODE_ENV=test\n - DB_HOST=postgres-test\n - DB_PORT=5432\n - DB_USER=test_user\n - DB_PASSWORD=test_pass\n - DB_NAME=test_db\n depends_on:\n postgres-test:\n condition: service_healthy\n command: ["npm", "run", "test:integration"]\n\n postgres-test:\n image: postgres:15-alpine\n environment:\n POSTGRES_USER: test_user\n POSTGRES_PASSWORD: test_