testcontainers-elixir
testcontainers-elixir copied to clipboard
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 contain...
Testcontainers
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
- Installation
- Usage
- API Documentation
- Contributing
- License
- Contact
Prerequisites
Before you begin, ensure you have met the following requirements:
- You have installed the latest version of Elixir
- You have a Docker runtime installed
- You are familiar with Elixir and Docker basics
Installation
To add Testcontainers to your project, follow these steps:
- Add
testcontainersto your list of dependencies inmix.exs:
def deps do
[
{:testcontainers, "~> x.x.x"}
]
end
-
Run mix deps.get
-
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.
Basic usage
You can use generic container api, where you have to define everything yourself:
{:ok, _} = Testcontainers.start_link()
config = %Testcontainers.Container{image: "redis:5.0.3-alpine"}
{:ok, container} = Testcontainers.start_container(config)
Or you can use one of many predefined containers like RedisContainer, that has waiting strategies among other things defined up front with good defaults:
{:ok, _} = Testcontainers.start_link()
config = Testcontainers.RedisContainer.new()
{:ok, container} = Testcontainers.start_container(config)
ExUnit tests
Given you have added Testcontainers.start_link() to test_helper.exs:
setup
config = Testcontainers.RedisContainer.new()
{:ok, container} = Testcontainers.start_container(config)
ExUnit.Callbacks.on_exit(fn -> Testcontainers.stop_container(container.container_id) end)
{:ok, %{redis: container}}
end
there is a macro that can simplify this down to a oneliner:
import Testcontainers.ExUnit
container(:redis, Testcontainers.RedisContainer.new())
In a Phoenix project:
To start a postgres container when running tests, that also enables testing of application initialization with database calls at startup, add this in application.ex:
# in config/dev.exs:
config :testcontainers,
enabled: true
database: "hello_dev"
# in config/test.exs:
config :testcontainers,
enabled: true
# in lib/hello/application.ex:
@impl true
def start(_type, _args) do
if Application.get_env(:testcontainers, :enabled, false) do
{:ok, _container} =
case Application.get_env(:testcontainers, :database) do
nil ->
Testcontainers.Ecto.postgres_container(app: :hello)
database ->
Testcontainers.Ecto.postgres_container(
app: :hello,
persistent_volume_name: "#{database}_data"
)
end
end
# .. other setup code
end
# in mix.exs
# comment out test alias and setup aliases for ecto
defp aliases do
[
setup: [
"deps.get",
# "ecto.setup",
"assets.setup",
"assets.build"
],
# "ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
# "ecto.reset": ["ecto.drop", "ecto.setup"],
# test: ["ecto.create --quiet", "ecto.migrate --quiet", "test"],
# ... SNIP
]
end
This will start a postgres container that will be terminated when the test process ends.
The database config in config/test.exs will be temporarily updated in-memory with the random host port on the container, and other properties like username, password and database. In most cases these will default to "test" unless overridden.
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:
Phoenix example
There is also another example repo without Phoenix, just a bare mix project, which show cases that the ecto dependencies are in fact optional:
Mix project
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!