Community modules
Testcontainers for Rust are provided as two separate crates: testcontainers and testcontainers-modules.
While testcontainers is the core crate that provides an API for working with containers in a test environment,
testcontainers-modules is a community-maintained crate that provides ready-to-use images (aka modules).
Usually, it's easier to depend on ready-to-use images, as it saves time and effort. This guide will show you how to use it.
1. Usage¶
- Depend on [testcontainers-modules] with necessary features (e.g
postgres,minioetc.)- Enable
blockingfeature if you want to use modules within synchronous tests (feature-gate forSyncRunner)
- Enable
- Then start using the modules inside your tests with either
AsyncRunnerorSyncRunner
Simple example of using postgres module with SyncRunner (blocking and postgres features enabled):
use testcontainers_modules::{postgres, testcontainers::runners::SyncRunner};
#[test]
fn test_with_postgres() {
let container = postgres::Postgres::default().start().unwrap();
let host_port = container.get_host_port_ipv4(5432).unwrap();
let connection_string = &format!(
"postgres://postgres:postgres@127.0.0.1:{host_port}/postgres",
);
}
You don't need to explicitly depend on
testcontainersas it's re-exported dependency oftestcontainers-moduleswith aligned version between these crates. For example:use testcontainers_modules::testcontainers::ImageExt;
You can also see examples for more details.
2. How to override module defaults¶
Sometimes it's necessary to override default settings of the module (e.g tag, name, environment variables etc.)
In order to do that, just use extension trait ImageExt
that returns a customized ContainerRequest:
use testcontainers_modules::{
redis::Redis,
testcontainers::{ContainerRequest, ImageExt},
};
/// Create a Redis module with `6.2-alpine` tag and custom password
fn create_redis() -> ContainerRequest<Redis> {
Redis::default()
.with_tag("6.2-alpine")
.with_env_var(("REDIS_PASSWORD", "my_secret_password"))
}
Pinning an image by digest¶
For reproducible pulls you can pin a module to an immutable content digest with
with_digest.
Unlike a tag, a digest can't be overwritten in the registry, so the exact same
image is used on every run. The digest must include the algorithm prefix (e.g.
sha256:...); the reference sent to Docker becomes name:tag@digest, and Docker
resolves the image by digest while the tag is kept for readability:
use testcontainers_modules::{
redis::Redis,
testcontainers::{ContainerRequest, ImageExt},
};
/// Pin the Redis module to a specific image digest
fn create_pinned_redis() -> ContainerRequest<Redis> {
Redis::default()
.with_tag("6.2-alpine")
.with_digest("sha256:e2c2f1f4c0a8b6d4e3f9a1b7c5d2e8f0a4b6c8d0e2f4a6b8c0d2e4f6a8b0c2d4")
}