jarlah

jarlah

Testcontainers - A Testcontainers implementation for Elixir

Testcontainers

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

It supports Testcontainers Desktop, but doesn’t need it to run. It will find and pick up a docker engine that works every time it runs.

Let me show you its features

In its basic form Testcontainers can used like this:

{:ok, _} = Testcontainers.start_link()
config = %Testcontainers.Container{image: "redis:latest"}
{:ok, container} = Testcontainers.start_container(config)

But the most interesting usage for Elixir is the Ecto module, which lets you run tests without having a postgres (or mysql) container running (see the README section for this advanced usage).

You can also spin up a throwaway container in a single ExUnit test:

container(:redis, Testcontainers.RedisContainer.new())

or shared container for multiple tests

container(:redis, Testcontainers.RedisContainer.new(), shared: true)

How it works

It has a dependency on an autogenerated elixir library for the docker engine api. The complex logic for calling out to docker is hidden inside that library.

Most Liked

jarlah

jarlah

Proud to announce v1.8.0 which brings support for two new technologies, RabbitMq and Emqx.

There are a lot of new contributors in this release and this is really encouraging.

Key features that has been implemented is private registry support and proper user agent is sent to docker engine api.

:raised_hands:

jarlah

jarlah

a friendly and helpful github user that previously reported podman not working, got back to me and told me that it was still not working after the release. Well i brought in the big guns, virtualbox, and installed ubuntu 24 and podman and started podman.socket service in user mode. Confirmed the issue, fixed the bug and released v1.11.5 :slight_smile: Thanks to github user kianmeng for this helpful testing.

jarlah

jarlah

New release v1.9.0 is out!

Check it out.

With mix task feature. And some dependabot updates.

jarlah

jarlah

A couple of bugfixes later I can now testify that the testcontainers library is actually usable now. With the introduction of the mix task and its reuse and watch functionality, i can attest for its usefulness.

If you are using it already, do a mix deps.update testcontainers and it will update the patch version. If not, adding it to deps with {:testcontainers, "~> 1.10", only: [:dev, :test], runtime: false} and running mix deps.get will get you up and running. Dont need to add anything in the test_helper.exs.

To use the testcontainers.test task you will need to adjust the config/test.exs so it reads db environment variables. From the readme, it can look like this:

config :my_app, MyApp.Repo,
  username: System.get_env("DB_USER") || "postgres",
  password: System.get_env("DB_PASSWORD") || "postgres",
  hostname: System.get_env("DB_HOST") || "localhost",
  port: System.get_env("DB_PORT") || "5432",
  database: "my_app_test#{System.get_env("MIX_TEST_PARTITION")}",
  pool: Ecto.Adapters.SQL.Sandbox,
  pool_size: System.schedulers_online() * 2

If you want to reuse the database container, add testcontainers.reuse.enable=true in ~/.testcontainers.properties.

Now you can run

mix testcontainers.test

It doesnt look as pretty as normal test runs, because it streams output from a System.cmd call to stdout, but its better than having to struggle with mix test.watch which have many unresolved issues. At least for me.

If you want to watch files for changes and rerun the tests when changed, run this instead:

mix testcontainers.test --watch lib --watch test

Its not a very complicated task, so if you cancel before the test run completes, it will run in the background as a separate os process. If you rerun the command above before its complete, and if you have reuse enabled in properties, you might encounter many fun issues.

I usually have another terminal open where i monitor docker:

watch docker ps

Any feedback on the mix task and the watching functionality would be wonderful :slight_smile: <3

jarlah

jarlah

Big news :rocket: Testcontainers for Elixir now has (rootless) podman support :muscle: :rocket: Read more here

I have had this nugget of a problem on my desk for quite some time now and its quite funny how easy it was to fix. The major problem was that I am not using podman myself. So had to test at work where they are using podman. And i have also added a github workflow to verify that everything works for both normal docker and podman.

Im very psyched about this because it opens for many more (security oriented) developers to start using the library :slight_smile:

Try it out and see how/if it works for you.

Where Next?

Popular in Announcing Top

jsm
Once is an Ecto type for locally unique 64-bits IDs generated by multiple Elixir nodes. Locally unique IDs make it easier to keep things ...
New
BartOtten
This powerful library works together with Phoenix Router to provide the ultimate routing solution. It simplifies route manipulation, givi...
New
Gigitsu
Hi everyone! I’d like to share a small library I’ve recently extracted from a project I’m working on: ginject. ginject provides a minim...
New
pcharbon
This is a new extension for the Ash framework that lets you use the Commanded library in a more declarative manner and removes most of th...
New
fuelen
Hi all! Confispex is a tool which allows defining specs for runtime configuration, cast values according to specified types and inspect ...
New
mikehostetler
LLM DB - LLM Model Metadata Package This package was extracted out of the ReqLLM project. LLM DB is a model metadata catalog with fast, ...
New
hauleth
It is library created by me and @abc3. It is simple client for DuckDB, but with small twist when compared with other libraries out there ...
New
corka149
A JSON patch is a way to define a sequence of manipulating operations on a JavaScript object. The IETF published the RFC 6902 - found he...
New
fhunleth
Elixir Circuits is a set of libraries for interacting with hardware. We previously announced Circuits.UART, and now we’re ready to announ...
New
waseigo
I saw this LinkedIn post: *Can your programming language do this? This is a macro in Clojure called `dotrace`. When you surround a pie...
New

Other popular topics Top

lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
beno
I will often find my self writing things similar to: case some_value do nil -&gt; something() "" -&gt; something() _ -&gt; someth...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers' Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
magnetic
Hey :wave:t3: Elixir community, I’ve been learning Elixir, and working on some side projects. My editor of choice is VSCode, and althoug...
New

We're in Beta

About us Mission Statement