Testcontainers Node Documentation
repository·main·Indexed 25 days ago
https://github.com/testcontainers/testcontainers-nodeA library for managing Docker containers within Node.js applications to provide ephemeral, reproducible environments for integration testing. It includes features for managing GenericContainers, Docker Compose environments via DockerComposeEnvironment, and low-level access to container runtimes like Docker, Podman, and Colima through the ContainerRuntimeClient.
What's inside Testcontainers Node
- Testcontainers is a library designed to support automated testing by providing lightweight, throwaway instances of common dependencies. It allows you to run databases, Selenium web browsers, or any other software that can run in a Docker container as part of your test lifecycle.
Overview of Testcontainers Node
mainTestcontainers is a library that provides lightweight, throwaway instances of common databases, instruction sets, or anything else that can run in a Docker container. It allows developers to manage the lifecycle of these containers (start, stop, etc.) directly from their code, making it ideal for integration testing.Use @testcontainers/azurite for Azure Storage emulation
mainThe
@testcontainers/azuritemodule allows you to run an Azurite container for testing Azure Blob, Queue, and Table storage.Common usage patterns include:
- Blob Storage: Uploading and downloading blobs.
- Queue Storage: Sending and receiving queue messages.
- Table Storage: Creating, inserting, and fetching data from tables.
- Persistence: Using in-memory persistence for testing.
- Security: Configuring custom credentials, HTTPS with PEM certificates, or OAuth.
- Networking: Mapping custom ports.
Note: When implementing, you may need to substitute
IMAGEwith a specific image from the Microsoft Azurite container registry.Important requirements for K3s container
mainThe K3s container runs in privileged mode because it spawns its own containers. Consequently, it will not function in environments that disallow privileged containers, such as certain rootless Docker configurations or specific Docker-in-Docker setups.Use MongoDBAtlasLocalContainer
mainThe
MongoDBAtlasLocalContainerprovides a MongoDB Atlas Local image, which combines the MongoDB database engine with MongoT for Atlas Search capabilities.Important Note: The connection string returned by
getConnectionString()does not includedirectConnection=true. When connecting with a MongoDB client, you must manually passdirectConnection: truein your client options.Reuse containers across tests
mainEnabling container re-use allows Testcontainers to skip starting a new container if a container with the exact same configuration is already running. This is useful for sharing a container across multiple tests without global setup.
To enable re-use, call
.withReuse()on your container instance. You can also re-use stopped containers if you set.withAutoRemove(false)before stopping them.Global control: You can enable or disable this feature globally using the
TESTCONTAINERS_REUSE_ENABLEenvironment variable. If not set, the feature is enabled by default.const container1 = await new GenericContainer("alpine") .withCommand(["sleep", "infinity"]) .withReuse() .start(); const container2 = await new GenericContainer("alpine") .withCommand(["sleep", "infinity"]) .withReuse() .start(); expect(container1.getId()).toBe(container2.getId());Share container data with tests using inject()
mainBecause
globalSetupruns in a different global scope than your individual test files, you cannot directly access variables defined in the setup script. To share data (like connection URLs), use theproject.provide(key, value)method in your setup script and retrieve it using theinject(key)function within your tests. The values provided must be serializable.import { afterAll, beforeAll, expect, inject, test } from "vitest"; import { createClient } from "redis"; // Retrieve the URL provided by the global setup const redisClient = createClient({ url: inject("redisUrl") }); beforeAll(async () => { await redisClient.connect(); }); afterAll(async () => { await redisClient.disconnect(); }); test("stores and reads a value", async () => { await redisClient.set("key", "test-value"); const result = await redisClient.get("key"); expect(result).toBe("test-value"); });Understand default wait strategies
mainTestcontainers uses a default selection logic for waiting:
- Health Check: If the image defines a health check or you use
.withHealthCheck(), Testcontainers waits for that health check to succeed. - Listening Ports: If no health check is defined (or if the image uses
HEALTHCHECK NONE), Testcontainers waits up to 60 seconds for mapped network ports to be bound.
You can override this behavior using
.withWaitStrategy().- Health Check: If the image defines a health check or you use
Compose multiple wait strategies
mainYou can chain multiple strategies together using
Wait.forAll([...]).- Timeouts: Each inner strategy respects its own
.withStartupTimeout(). If an inner strategy doesn't have one, it inherits the timeout set on the composite via.withStartupTimeout(). - Deadlines: You can use
.withDeadline(ms)on the composite strategy. The composite will throw an error unless all inner strategies resolve before this deadline.
const { GenericContainer, Wait } = require("testcontainers"); // Wait for both ports AND a log message const container = await new GenericContainer("alpine") .withWaitStrategy(Wait.forAll([ Wait.forListeningPorts(), Wait.forLogMessage("Ready to accept connections") ])) .start(); // Using a deadline for the entire composite const compositeWithDeadline = Wait.forAll([Wait.forListeningPorts(), Wait.forLogMessage("READY")]) .withDeadline(2000);- Timeouts: Each inner strategy respects its own
Install @testcontainers/azurite
mainTo use Azurite with Testcontainers, install the module as a development dependency using npm:
npm install @testcontainers/azurite --save-devStart a container with GenericContainer
mainUse
GenericContainerto create and start any Docker container. You can specify the image name and version directly in the constructor.Note: Testcontainers automatically pulls images if they are not present locally, but you can configure the pull policy.
const { GenericContainer } = require("testcontainers"); // Start a container with default image const container = await new GenericContainer("alpine").start(); // Start a container with a specific version const container = await new GenericContainer("alpine:3.10").start();Install @testcontainers/mssqlserver
mainTo use MSSQL Server with Testcontainers, install the module as a development dependency using npm.
npm install @testcontainers/mssqlserver --save-dev