Skip to content

Commit

Permalink
feat: add mix task for running tests under testcontainers (#124)
Browse files Browse the repository at this point in the history
  • Loading branch information
jarlah authored Sep 23, 2024
1 parent 8958b6f commit 3d23f9a
Show file tree
Hide file tree
Showing 10 changed files with 105 additions and 85 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/elixir.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ jobs:
run: |
cd examples/phoenix_project
mix deps.get
mix test
mix testcontainers.test
MIX_ENV=prod mix release
- name: Run example mix project tests
run: |
Expand Down
2 changes: 2 additions & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
erlang 25.3.2.13
elixir 1.17-otp-25
75 changes: 16 additions & 59 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,71 +96,28 @@ import Testcontainers.ExUnit
container(:redis, Testcontainers.RedisContainer.new())
```

### In a Phoenix project:
### Run tests in a Phoenix project (or any project for that matter)

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:
To run/wrap testcontainers around a project use the testcontainers.test task.

```elixir
# 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.
`mix testcontainers.test [--database postgres|mysql]`

See documentation on [Testcontainers.Ecto](https://hexdocs.pm/testcontainers/Testcontainers.Ecto.html) for more information about the options it can take.
to use postgres you can just run

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:
`mix testcontainers.test` since postgres is default.

[Phoenix example](./examples/phoenix_project)
in your config/test.exs you can then change the repo config to this:

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](./examples/mix_project)
```
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
```

### Logging

Expand Down
7 changes: 4 additions & 3 deletions examples/phoenix_project/config/dev.exs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import Config

# Configure your database
config :hello, Hello.Repo,
username: "postgres",
password: "postgres",
hostname: "localhost",
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: "hello_dev",
stacktrace: true,
show_sensitive_data_on_connection_error: true,
Expand Down
7 changes: 4 additions & 3 deletions examples/phoenix_project/config/test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ config :testcontainers, enabled: true
# to provide built-in test partitioning in CI environment.
# Run `mix help test` for more information.
config :hello, Hello.Repo,
username: "postgres",
password: "postgres",
hostname: "localhost",
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: "hello_test#{System.get_env("MIX_TEST_PARTITION")}",
pool: Ecto.Adapters.SQL.Sandbox,
pool_size: 10
Expand Down
Loading

0 comments on commit 3d23f9a

Please sign in to comment.