I have a question about your workflow (or the canonical docker-based workflow) - are you supposed to run tests in a different docker container? Or just locally w/ no container? Or is there a way to change the env to TEST for this container? I like to do red-green-refactor TDD, so quick & easy tests are a big thing for me. I got my tests running locally, but I assume that's not optimal because my local postgres and erlang versions (and db credentials) are different than what is in the container.
Software engineer. Currently working with TypeScript, Ruby and Terraform to build digital solutions! Enthusiast about Elixir, OTP, design patterns and best practices.
Good question! I'm running my tests inside the local development container with command docker-compose run -e MIX_ENV=test web mix test. That command will replace the MIX_ENV environment variable with value "test", so when the mix test is executed the mix environment is set to test, not dev.
About the database url, the smartest way to use environment defined database URL is to use wildcard character in the database name, for example, postgres://postgres:postgres@db:5432/myapp_?. This way in the config files we can read that URL from container environment, replace the ? with our actual environment respectively (dev, test, even prod). By going this, you will always have separate databases locally for development and testing, and the development data does not affect test cases.
Is that wildcard substitution something I do manually w/ String.replace or interpolation, or is there something built-in to the config function that I am unaware of?
So far the only thing I got to work was: # .env
DATABASE_URL=postgres://postgres:postgres@db:5432/my_app_ # dev.exs
database_url = "#{System.get_env("DATABASE_URL")}#{Mix.env()}"
Software engineer. Currently working with TypeScript, Ruby and Terraform to build digital solutions! Enthusiast about Elixir, OTP, design patterns and best practices.
That Mix.env() is one way to achieve that. Personally I would still use String.replace/3, since Elixir 1.9 introduced a new way to configure your application without Mix dependency in your config-files.
I have a question about your workflow (or the canonical docker-based workflow) - are you supposed to run tests in a different docker container? Or just locally w/ no container? Or is there a way to change the env to TEST for this container? I like to do red-green-refactor TDD, so quick & easy tests are a big thing for me. I got my tests running locally, but I assume that's not optimal because my local postgres and erlang versions (and db credentials) are different than what is in the container.
Good question! I'm running my tests inside the local development container with command
docker-compose run -e MIX_ENV=test web mix test
. That command will replace theMIX_ENV
environment variable with value "test", so when themix test
is executed the mix environment is set to test, not dev.About the database url, the smartest way to use environment defined database URL is to use wildcard character in the database name, for example,
postgres://postgres:postgres@db:5432/myapp_?
. This way in the config files we can read that URL from container environment, replace the?
with our actual environment respectively (dev, test, even prod). By going this, you will always have separate databases locally for development and testing, and the development data does not affect test cases.Is that wildcard substitution something I do manually w/ String.replace or interpolation, or is there something built-in to the config function that I am unaware of?
So far the only thing I got to work was:
# .env
DATABASE_URL=postgres://postgres:postgres@db:5432/my_app_
# dev.exs
database_url = "#{System.get_env("DATABASE_URL")}#{Mix.env()}"
That
Mix.env()
is one way to achieve that. Personally I would still useString.replace/3
, since Elixir 1.9 introduced a new way to configure your application without Mix dependency in your config-files.I would do it this way:
test.exs
.env