alvinncx
Writing Tests for Multitenancy solution
Ever since I’ve started on Elixir, I’ve fell in love
with writing tests for my applications.
For the most part, writing tests for a regular Phoenix + Ecto + ExMachina stack has been a breeze since it is well documented.
Recently, I’ve been working on an application that is multi-tenant in nature and it’s been a pain to write tests with existing tools.
The current design is to have a different database schema for every tenant. I’m looking for advise for these questions:
- Should I set up and teardown the test database everytime?
- Should I use ExMachina here? It doesn’t seem to support prefixes yet.
Would be open to hear other advise as well (test methodology, approaches, etc). Thanks!
Most Liked
alvinncx
So I somewhat got this sorted out. Posting my experiences so maybe it will help someone out.
This post was helpful for me to structure the application for multi-tenancy.
A dive into database multi-tenancy in Elixir with Ecto. I also used the example github repo in the post as reference to help me.
There are a few pointers in case anyone out there gets stuck with the same issues:
-
First, I stopped using factories (ExMachina). I moved all my fixtures into a single module and used
Repo.insert!where ever I needed to interact. Since tests are ran in sandboxed environment I didn’t find a lot of advantages to continue using ExMachina, especially since it doesn’t support prefixes. -
At first I thought it would be a bad idea to teardown the database and migrate for each test suite… It turns out the tenant migrations are very fast so there isn’t a big hit to test productivity. What I did is add
ecto.dropto the start of the test script inmix.exs. Effectively I rebuild the database for every test run. -
Because of the issue in 2), I can’t really use
create extensionseffectively. This caused me to move row defaults into the application instead. Not a major issue, but something to take note of. -
Take note that schema migrations don’t currently work in a transaction using Ecto 3 Migrator. The problem is documented here
Ecto 3 Support · Issue #59 · ateliware/triplex · GitHub. This particular issue had me scratching my head for a long time, until I dug into github.
JohnnyCurran
We use multi tenancy and ExMachina. It’s fairly straightforward and you don’t have to ditch your factories.
You’re going to want to define an EctoStrategy module:
defmodule MyProj.EctoStrategy do
use ExMachina.Strategy, function_name: :insert
def handle_insert(struct, attributes) do
# Determine DB schema prefix to use
ExMachina.EctoStrategy.handle_insert(struct, attributes, prefix: prefix)
end
end
defmodule MyProj.Factory do
use ExMachina
use MyProj.EctoStrategy
# Factory definitions
end
dimitarvp
This might be a generic and not very helpful reply (sorry), but for posterity I feel obliged to mention Ecto.Adapters.SQL.Sandbox — Ecto SQL v3.14.0 – have you read through it? Have you tried its different modes of operation?
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #javascript
- #code-sync
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance








