Testcontainers

Hex.pm

Testcontainers is an Elixir library that supports ExUnit tests, providing lightweight, throwaway instances of common databases, Selenium web browsers, or anything else that can run in a Docker container.

Table of Contents

Prerequisites

Before you begin, ensure you have met the following requirements:

Installation

To add Testcontainers to your project, follow these steps:

  1. Add testcontainers to your list of dependencies in mix.exs:
def deps do
  [
    {:testcontainers, "~> x.x.x"}
  ]
end
  1. Run mix deps.get

  2. Add the following to test/test_helper.exs

Testcontainers.start_link()

Usage

This section explains how to use the Testcontainers library in your own project.

In a Phoenix project:

In simple terms you can add this in application.ex:

  # In your application.ex file in your Phoenix project:

  import Testcontainers.Ecto

  @impl true
  def start(_type, _args) do
    if Mix.env() == :test,
      do:
        postgres_container(
          app: :my_app,
          user: "postgres",
          password: "postgres"
        )

    # .. other setup code
  end

see documentation on Testcontainers.Ecto for more information about the options it can take.

There is an example repo here with a bare bones phoenix application, where the only changes are the use of the ecto function and removing the test alias that interferes with it:

https://github.com/jarlah/hello_testcontainers

There is also another example repo without Phoenix, just a bare mix project, which show cases that the ecto dependencies are in fact optional:

https://github.com/jarlah/mix_teststcontainers

In your ExUnit tests

Here's a simple example of how to use a MySQL container in your ExUnit tests:

# test/simple_mysql_container_test.exs

defmodule SimpleMySqlContainerTest do
  use ExUnit.Case, async: true

  import Testcontainers.ExUnit

  alias Testcontainers.Container.MySqlContainer

  describe "with default configuration" do
    container(:mysql, MySqlContainer.new())

    test "provides a ready-to-use mysql container", %{mysql: mysql} do
      assert mysql.environment[:MYSQL_MAJOR] == "8.0"
    end
  end
end

You can also define a shared container for all tests in a test module:

# test/shared_mysql_container_test.exs

defmodule SharedMySqlContainerTest do
  use ExUnit.Case, async: true

  import Testcontainers.ExUnit

  alias Testcontainers.Container.MySqlContainer

  container(:mysql, MySqlContainer.new(), shared: true)

  describe "with default configuration" do
    test "provides a ready-to-use mysql container", %{mysql: mysql} do
      assert mysql.environment[:MYSQL_MAJOR] == "8.0"
    end

    test "does something else", %{mysql: mysql} do
      # ....
    end
  end
end

In the last example only one container will be created and started.

Logging

By default, Testcontainers doesn't log anything. If you want Testcontainers to log, set the desired log level in config/test.exs:

# config/test.exs

import Config 

config :testcontainers,
  log_level: :warning

API Documentation

For more detailed information about the API, different container configurations, and advanced usage scenarios, please refer to the API documentation.

Contributing

We welcome your contributions! Please see our contributing guidelines (TBD) for more details on how to submit patches and the contribution workflow.

License

Testcontainers is available under the MIT license. See the LICENSE file for more info.

Contact

If you have any questions, issues, or want to contribute, feel free to contact us.


Thank you for using Testcontainers to test your Elixir applications!