Search code examples
elixirphoenix-frameworkex-unit

Elixir / Phoenix - Run code at the very beginning of a test run, shared data for ALL tests


I'd like to run a block of code right at the beginning of my test suite (that inserts data into the database!), and persists across the entirety of the test suite.

Is something like this possible?

I tried running the code in a setup_all block, but: A) I was getting failures trying to insert into the database here; B) This would only be shared between that test module, whereas I'd like it to be shared across all tests.

Thanks for your help!


Solution

  • Run once before starting tests

    Just put the common code in your test/test_helper.exs:

    ExUnit.start()
    
    # Common Code
    ModuleOne.some_method
    ModuleTwo.other_method(args) # etc
    

    Run before every test

    Assuming you have already worked out cleaning up the db and running migrations between tests, you can put something like this in your test/test_helper.exs:

    defmodule TestProject.Helpers do
      def setup do
        # Common Code
      end
    end
    

    And use this setup block in all of your tests:

    setup do
      TestProject.Helpers.setup
    end
    

    Setting up a Test Database / Schema

    If you also need to set up a fake Database, Schema and Migrations for your tests, you'll need to define them as well, and put this in your test_helper (assuming here that the driver you are using is Postgrex):

    # Start Ecto
    {:ok, _} = Ecto.Adapters.Postgres.ensure_all_started(TestProject.Repo, :temporary)
    _        = Ecto.Adapters.Postgres.storage_down(TestProject.Repo.config)
    :ok      = Ecto.Adapters.Postgres.storage_up(TestProject.Repo.config)
    {:ok, _} = TestProject.Repo.start_link
    

    For a more detailed example, you can see my Ecto.Rut package that creates a fake database (for the test env only), and resets it before running each test.