Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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

FeatureDescription
Container LifecycleAutomatic start, stop, and cleanup
Port MappingDynamic port allocation with easy access
Wait StrategiesPort, log, HTTP, exec, and health check waiting
NetworksIsolated Docker networks for multi-container tests
File OperationsCopy files to and from containers
Pre-built ModulesPostgreSQL, 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.