Quickly embed Phoenix sample apps in your project for library development.
In order to build packages for Phoenix applications, it may be necessary to load a running Phoenix project in development and tests. However, when you ship your library you want to be sure that neither the Phoenix test app nor any of its dependencies are leaked into your distribution.
It is possible to embed a Phoenix project into a subdirectory of your project as a dev and test dependency, with full access to its modules and dependencies in your tests and dev environment. You can even start the server directly from your root project directory with mix phx.server
or iex -S mix phx.server
, just as you would in a normal Phoenix project.
phx_test
is avaialble on hex.pm. See the official documentation on hexdocs.
def deps do
[
{:phx_test, "~> 0.1.0", only: [:dev, :test]}
]
end
$ mix phx_test.new # generates /priv/phx_test_app/ (default)
$ mix phx_test.new my_app # generates /priv/my_app/
$ mix phx_test.new my_app --sub-directory sample_apps # generates /sample_apps/my_app/
$ mix phx_test.new --no-ecto --no-dashboard --no-mailer --no-gettext
This task wraps mix phx.new
and adds some conveniences for embedding a sample Phoenix app inside of another project for development and testing purposes. By default mix phx_test.new
will generate a new Phoenix project called phx_test_app
in the priv/
directory. You can also specify a custom app name and subdirectory with mix phx_test.new APP_PATH [--sub-directory DIR]
. All other options are passed directly to mix phx.new
, except --umbrella
, which mix phx_test.new
does not support.
Your new Phoenix app will be automatically added as a dev and test dependency, along with a couple others. Here's the full list of dependencies that will be injected into your root project's mix.exs
:
{:phx_test_app, path: "./priv/phx_test_app", only: [:test, :dev]}, # customized for your test app
{:phoenix_live_reload, "~> 1.2", only: :dev},
{:floki, ">= 0.30.0", only: :test}
Your new Phoenix app will bring its own dependencies along with it for your dev and test environments. floki
and phoenix_live_reload
must be added explicitly, because as dev and test dependencies of your Phoenix project they are not automatically brought into your root project. None of these dependencies will leak into your production environment by default.
The mix phx_test.new
task will also create a config/config.exs
file if it doesn't exist and import the newly generated Phoenix project's config, or inject the import statement into your existing config. This is necessary to properly configure your new Phoenix application so you can run it during development and tests.
If you are developing a library package distribution, neither the Phoenix project nor any of its config or dependencies will be included with your package as long as you do not include the path to the project in your package()[:files]
option in mix.exs
.
If you are developing a production application and want to make sure that the embedded Phoenix project's config does not leak into your production environment, simply move the import_config "../<sub_directory>/<app_name>/config/config.exs"
statement into your desired environment config file (dev.exs
, test.exs
, etc.).
If your new Phoenix app was installed with Ecto (you can exclude Ecto by passing the --no-ecto
switch to mix phx_test.new
) then you will have to explicitly run database tasks in the test environment. In a normal Phoenix project mix test
quietly takes care of this for you, but this will not be the case when running tests in your root project directory. For example:
$ cd priv/phx_test_app/
$ mix ecto.create
$ MIX_ENV=test mix ecto.create
$ cd ../..
$ mix test
You will be able to start the server for your new Phoenix test app simply by running mix phx.server
from your root project directory. iex -S mix phx.server
also works as expected, and all modules from your root project and the Phoenix app will be loaded and available in IEx
sessions for both development and test environments.
mix phx_test.new
injects the following code into your test/test_helper.exs
to explicitly require your new Phoenix app's test modules:
# naming is customized for your generated app
Code.require_file("priv/phx_test_app/test/test_helper.exs")
Code.require_file("priv/phx_test_app/test/support/data_case.ex")
Code.require_file("priv/phx_test_app/test/support/conn_case.ex")
Now when running tests with your new Phoenix test app, you are able to use the default ConnCase
and DataCase
that are included automatically by Phoenix from your root project's tests. For example:
# test/root_project/phx_test_app_test.exs
defmodule RootProject.PhxTestAppTest do
use PhxTestAppWeb.ConnCase
test "/", %{conn: conn} do
assert conn
|> get("/")
|> html_response(200) =~ "Welcome to Phoenix!"
end
end
Since your Phoenix test app is now a test dependency of your root project, all of your Phoenix test app's modules will be loaded for tests by default.
Creating umbrella test apps is not supported.
MIT - Copyright (c) 2022 M. Simon Borg
Pull requests are welcome. I encourage you to open an issue first so we can discuss the idea, and so you can be sure that the work you're proposing isn't already in development.