Starting up application (a Repo) only for tests?

We have an application that we use to access a PostGres database using Ecto – let’s refer to it as the SharedDb app. This SharedDb application doesn’t do much on its own – usually other applications list it as a dependency and the other applications put it into their own supervision trees.

However, I noticed a problem when I started to write tests for this SharedDb app: it doesn’t start up the Ecto Repo – so I can’t actually test any database inserts. My question is:

Is it possible to start up the Ecto Repo process only in the test environment?
I did something like this for a similar app a while ago:

defmodule SharedDb.Application do
  use Application

  def start(_type, _args) do
    import Supervisor.Spec, warn: false
    children = [supervisor(SharedDb.Repo, [])]
    opts = [strategy: :one_for_one, name: SharedDb.Supervisor]
    Supervisor.start_link(children, opts)
  end
end

but in our case, we explicitly require that the other apps supervise this one.

I am not an expert with any of the supervision / process stuff, so any guidance here is much appreciated. Thanks!

I have been writing an ecto extension, that use a fake Repo for test… It doesn’t have an application tree, just a library to extend ecto. But even like this it is fully testable, with fake Schemas and fake Repo.

You might get inspiration for configuration.

I create this fake Repo in test/test_helper, to be used for test only.

PS: It’s a work in progress, without doc, but You can see the mix.exs and test/test_helper files. It is meant to add acts as nested set and acts as list features to Ecto.

This is dependencies

      {:ecto, ">= 3.0.0"},

      # Test dependencies
      {:ecto_sql, ">= 3.0.0", only: :test},
      {:postgrex, ">= 0.15.0", only: :test},

This is the start of test_helper.

ExUnit.start()

alias Ecto.Integration.TestRepo
alias Ecto.Multi

Application.put_env(
  :ecto,
  TestRepo,
  adapter: Ecto.Adapters.Postgres,
  url: System.get_env("DATABASE_URL", "ecto://localhost/ecto_network_test"),
  pool: Ecto.Adapters.SQL.Sandbox
)

defmodule Ecto.Integration.TestRepo do
  use Ecto.Repo,
    otp_app: :ecto,
    adapter: Ecto.Adapters.Postgres
end

{:ok, _} = Ecto.Adapters.Postgres.ensure_all_started(TestRepo, :temporary)

_ = Ecto.Adapters.Postgres.storage_down(TestRepo.config())
:ok = Ecto.Adapters.Postgres.storage_up(TestRepo.config())

{:ok, _pid} = TestRepo.start_link()

Code.require_file("ecto_migration.exs", __DIR__)

:ok = Ecto.Migrator.up(TestRepo, 0, Ecto.Integration.Migration, log: false)
Ecto.Adapters.SQL.Sandbox.mode(TestRepo, :manual)
Process.flag(:trap_exit, true)

# this file continue with fake schemas...

As You can see, it’s possible to use a fake application, with a fake repo, for test only.

1 Like

Brilliant! Thank you! I came up with an alteration like the following:

# config/test.exs
import Config

config :shared_db, SharedDb.Repo,
       # ... test credentials ...
       adapter: Ecto.Adapters.Postgres,
       pool: Ecto.Adapters.SQL.Sandbox
# test_helper.exs
ExUnit.start()

alias SharedDb.Repo
{:ok, _} = Ecto.Adapters.Postgres.ensure_all_started(Repo, :temporary)

# This cleans up the test database and loads the schema
Mix.Task.run("ecto.drop")
Mix.Task.run("ecto.create")
Mix.Task.run("ecto.load")

# Start a process ONLY for our test run.
{:ok, _pid} = Repo.start_link()

Thank you, I relay needed this topic, it saved me.
But when we have no config file in our project, how can skip this warning? My test passed, but I have this error in my terminal.

warning: could not find Ecto repos in any of the apps: [:mishka_developer_tools].

You can avoid this warning by passing the -r flag or by setting the
repositories managed by those applications in your config/config.exs:

    config :mishka_developer_tools, ecto_repos: [...]

warning: could not find Ecto repos in any of the apps: [:mishka_developer_tools].

You can avoid this warning by passing the -r flag or by setting the
repositories managed by those applications in your config/config.exs:

    config :mishka_developer_tools, ecto_repos: [...]

warning: could not find Ecto repos in any of the apps: [:mishka_developer_tools].

You can avoid this warning by passing the -r flag or by setting the
repositories managed by those applications in your config/config.exs:

    config :mishka_developer_tools, ecto_repos: [...]

Updated

I deleted these lines

Mix.Task.run("ecto.drop")	
Mix.Task.run("ecto.create")	
Mix.Task.run("ecto.load")

and it works now without warning