testcontainers_gleam

Package Version Hex Docs

Gleam wrapper around Elixir TestContainers for managing Docker containers in tests.

Installation

gleam add --dev testcontainers_gleam

Mind that elixir is required to use this library, as it wraps an Elixir dependency. You can install Elixir from the official website.

Quick start

import testcontainers_gleam
import testcontainers_gleam/container

pub fn demo_test() {
  // Build a container definition
  let c =
    container.new("redis:7.4-alpine")
    |> container.with_exposed_port(6379)
    |> container.with_environment("REDIS_PASSWORD", "secret")

  // Start the container (GenServer is started automatically)
  let assert Ok(running) = testcontainers_gleam.start_container(c)

  // Query the running container
  let id = container.container_id(running)
  let assert Ok(host_port) = container.mapped_port(running, 6379)

  // ... use host_port to connect to Redis ...

  // Stop the container
  let assert Ok(Nil) = testcontainers_gleam.stop_container(id)
}

Container configuration

The container module exposes a builder API for configuring containers:

import testcontainers_gleam/container
import testcontainers_gleam/wait_strategy

container.new("postgres:16-alpine")
|> container.with_exposed_port(5432)
|> container.with_environment("POSTGRES_PASSWORD", "test")
|> container.with_cmd(["postgres", "-c", "log_statement=all"])
|> container.with_label("project", "my_app")
|> container.with_waiting_strategy(
  wait_strategy.log("database system is ready to accept connections", 30_000, 1000),
)
|> container.with_auto_remove(True)

Available builder functions

FunctionDescription
with_exposed_portExpose a single port (mapped to a random host port)
with_exposed_portsExpose multiple ports at once
with_fixed_portBind a container port to a specific host port
with_environmentSet an environment variable
with_cmdSet the container command
with_bind_mountMount a host path into the container
with_bind_volumeMount a named Docker volume
with_labelAdd a container label
with_waiting_strategyAdd a readiness wait strategy
with_auto_removeAuto-remove the container on exit
with_reuseReuse containers across test runs
with_network_modeSet the network mode ("bridge", "host", etc.)
with_authSet registry credentials for private images
with_check_imageSet an image name validation pattern
with_pull_policySet the pull policy (AlwaysPull or NeverPull)

Wait strategies

Wait strategies control how testcontainers detects that a container is ready:

import testcontainers_gleam/wait_strategy

// Wait for a TCP port to accept connections
wait_strategy.port("0.0.0.0", 5432, 5000, 500)

// Wait for a log line matching a regex pattern
wait_strategy.log("Ready to accept connections", 10_000, 1000)

// Wait for a command to exit with status 0
wait_strategy.command(["pg_isready"], 10_000, 1000)

All strategies take timeout (max wait in ms) and retry_delay (polling interval in ms) parameters.

Requirements

Further documentation can be found at https://hexdocs.pm/testcontainers_gleam.

Troubleshooting integration tests on CI

This doesn’t seem to be always necessary, but in case you are experiencing issues such as:

An unexpected error occurred:
  [Id([1]), Reason(Undefined), Desc(Undefined), Spawn(Undefined), Order(Undefined)]
gleeunit.main
An unexpected error occurred:
  [Id([]), Reason(Blame([1, 1])), Desc(Undefined), Spawn(Undefined), Order(Undefined)]

it may required to run the tests as follows.

testcontainers-gleam provides a test runner and guard function for integration tests that start Docker containers.

Test runner

Replace gleeunit.main() with integration.main() in your test entry point. This gives each test a 600-second timeout instead of gleeunit’s default 5 seconds, which is too short for container startup. It also automatically disables the Ryuk sidecar container, which fails in most CI environments:

// test/my_project_test.gleam
import testcontainers_gleam/integration

pub fn main() {
  integration.main()
}

Gating integration tests

Use integration.guard() to skip individual tests when the TESTCONTAINERS_INTEGRATION_TESTS environment variable is not set:

pub fn redis_test() {
  use <- integration.guard()
  let assert Ok(running) = testcontainers_gleam.start_container(container)
  // ...
}

CI configuration

Add these to your CI workflow:

- run: gleam test
  env:
    TESTCONTAINERS_INTEGRATION_TESTS: 1

Development

gleam deps download                                                            # Download dependencies
TESTCONTAINERS_INTEGRATION_TESTS=1 gleam test   # Run the tests (requires Docker)
gleam format src test                                                          # Format code

License

testcontainers-gleam is licensed under the MIT license. See full license HERE

Search Document