Multitenancy: How To Set Up a Tenant Database for testing purpose

I am working on a multitenant application and each time I run the test, a tenant has to be created, which runs that tenant migrations and this takes over 1.5 seconds per test.

Is there a way of preparing a tenant database to use for all tests once for all? I want to create a database and seed it at the beginning of the tests, then reuse it for all subsquent tests. Any guide/ example are appreciated.

I managed to solve it. Here is how I did it.

in test/test_helpers.exs I changed it to looking like the following, so that when the test starts, it creates the tenant owner and the tenant and gives all permissions required.


  :ok = Ecto.Adapters.SQL.Sandbox.checkout(Hr.Repo)
  
  # Set the sandbox mode to shared across processes
  Ecto.Adapters.SQL.Sandbox.mode(Hr.Repo, {:shared, self()})
  
  tenant_attrs = %{name: "Test Org", domain: "test_org"}
  user_attrs = %{email: "root_user@example.com", hashed_password: "so-secure!"}
  
  new_user = Ash.Seed.seed!(Hr.Accounts.User, user_attrs)
  tenant = Ash.Seed.seed!(Hr.Accounts.Organisation, tenant_attrs)
  
  Hr.Accounts.set_user_current_organisation!(new_user.id, %{
    current_organisation_id: tenant.id,
    current_tenant: tenant.domain
  })

Then in test/support/conn_case.ex I replaced the setup/1 function with the following:

defmodule MyAppWeb.ConnCase do

  use ExUnit.CaseTemplate
  # ...
  #Replace setup with the following.
  setup_all _tags do
    conn = Phoenix.ConnTest.build_conn()
    {user, auth_conn} = MyAppWeb.AuthCase.login_logic(conn)

    {:ok, auth_conn: auth_conn, conn: conn, user: user}
  end
end
2 Likes