Introduction
Testcontainers OCaml is a library that provides lightweight, disposable containers for integration testing. It enables OCaml developers to write tests against real servicesβdatabases, message queues, and other infrastructureβwithout complex setup or shared test environments.
Why Testcontainers?
Integration tests that rely on mocks or in-memory implementations often miss real-world bugs. Configuration mismatches, protocol differences, and edge cases in actual services go undetected until production.
Testcontainers solves this by:
- Running real services in Docker containers during tests
- Isolating each test run with fresh, disposable containers
- Managing lifecycle automaticallyβcontainers start before tests and terminate after
- Providing consistent environments across local development and CI/CD
Why OCaml?
OCaml's type system and emphasis on correctness make it an excellent choice for building reliable systems. Testcontainers OCaml brings the same philosophy to testing:
- Type-safe container configuration using the builder pattern
- Lwt-based async operations that integrate naturally with OCaml's async ecosystem
- Functional API design with composable wait strategies and configuration
Example
A complete integration test with PostgreSQL:
open Lwt.Syntax
open Testcontainers
let test_database () =
Postgres_container.with_postgres
~config:(fun c -> c
|> Postgres_container.with_database "myapp"
|> Postgres_container.with_username "test"
|> Postgres_container.with_password "secret")
(fun container connection_string ->
(* connection_string: postgresql://test:secret@127.0.0.1:54321/myapp *)
let* result = My_db.query connection_string "SELECT 1" in
assert (result = 1);
Lwt.return_unit)
The container starts automatically, waits until PostgreSQL is ready to accept connections, runs your test, and cleans upβregardless of whether the test passes or fails.
Features
| Feature | Description |
|---|---|
| Container Lifecycle | Automatic start, stop, and cleanup |
| Port Mapping | Dynamic port allocation with easy access |
| Wait Strategies | Port, log, HTTP, exec, and health check waiting |
| Networks | Isolated Docker networks for multi-container tests |
| File Operations | Copy files to and from containers |
| Pre-built Modules | PostgreSQL, MySQL, MongoDB, Redis, RabbitMQ |
Architecture
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Your Test Code β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Testcontainers OCaml β
β βββββββββββββββ βββββββββββββββ βββββββββββββββ β
β β Container β β Wait β β Network β β
β β Request β β Strategy β β Module β β
β βββββββββββββββ βββββββββββββββ βββββββββββββββ β
β βββββββββββββββββββββββββββββββββββββββββββββββ β
β β Docker Client (Unix Socket) β β
β βββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Docker Engine β
β ββββββββββββ ββββββββββββ ββββββββββββ β
β β Postgres β β Redis β β MySQL β ... β
β ββββββββββββ ββββββββββββ ββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Prior Art
This library is inspired by:
License
Testcontainers OCaml is released under the Apache License 2.0.