How to seed database for testing?

Tags: #<Tag:0x00007f039c7cdca0>


I have a seed.exs and I want to use it before mix test to seed db and then use that data inside tests. How do I do that?

What is the best way to generate seed data for end-to-end testing

You can run your seeds inside the test_helper.exs file. It’s always evaluated before the tests.



Thanks Michał.


Another way to do it currently is to call add run path/to/test_seeds.exs to the test alias in the projects mix.exs:

  defp aliases do
      "ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
      "ecto.reset": ["ecto.drop", "ecto.setup"],
      "test": ["ecto.create --quiet", "ecto.migrate", "run test/test_seeds.exs", "test"]

One thing to keep in mind though is that the seeds are run (of course) every time mix test is invoked, so the seeds will probably need to have some kind of conditional logic in place to only insert items in case they do not exist yet, something like this for example:

alias Foo.Category
alias Foo.Repo

if !Repo.get_by(Category, name: "fascinating") do
  Repo.insert(%Category{name: "fascinating"})

Then again, it might be more appropriate to insert the needed database records within the tests itself (or case file), which might make the tests a bit more explicit and self-contained and no conditional logic would be needed because tests are run within a transaction/cleaned up automatically.


In order to call the seeds from inside test_helper.exs, one option is to move the seeds file into a separate module:

defmodule MyApp.Seeds do
  def call do
    # Seed actions

Then can easily be called from either priv/repo/seeds.exs or test/test_helper.exs.

Thanks to Ihor Katkov in the #ecto Slack channel for proposing the solution.