phx_test
Inspired by this topic by @caleb-bb, I’ve been working on a little experiment called phx_test. The question was “how do I write tests for my LiveView development tool, without turning my libary into a Phoenix project?”. I don’t know where this project will go in the future, so I’d love your thoughts and feedback.
Problem
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.
Solution
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.
The path to making this work is not too complex, but it’s not obviously apparent either. Setting this up can save you from starting a separate Phoenix project and importing your libary just so you can perform tests. Now you can manage both your core project and the Phoenix app you use for testing in one repo.
mix phx_test.new
When you add phx_test
as a dev/test dependency to your project, you get the mix phx_test.new
task to set this up with one command. When you run this task with no arguments you will get a Phoenix project named phx_test_app
installed in the priv/
subdirectory, and some additional code injected into mix.exs
, config/config.exs
, and test/test_helper.exs
to hook everything up. Notably you will have the following dev/test dependencies added to your project’s mix.exs
:
{:phx_test_app, path: "./priv/phx_test_app", only: [:test, :dev]},
{:phoenix_live_reload, "~> 1.2", only: :dev},
{:floki, ">= 0.30.0", only: :test}
You can customize the test app’s name and location with options: mix phx_test.new bar --sub-directory foo
will create a Phoenix app called Bar
in the foo/bar
directory. The app name and all other options besides --sub-directory
are passed directly to mix phx.new
, so you can do things like mix phx_test.new bar --no-ecto --no-mailer --no-dashboard --no-gettext --sub-directory foo
. The only option that does not work with mix phx_test.new
is --umbrella
, but I don’t think that’s going to hold anyone back from running some tests
Feedback!
̶R̶i̶g̶h̶t̶ ̶n̶o̶w̶ ̶t̶h̶i̶s̶ ̶i̶s̶ ̶j̶u̶s̶t̶ ̶a̶v̶a̶i̶l̶a̶b̶l̶e̶ ̶o̶n̶ ̶[̶g̶i̶t̶h̶u̶b̶]̶(̶h̶t̶t̶p̶s̶:̶/̶/̶g̶i̶t̶h̶u̶b̶.̶c̶o̶m̶/̶m̶s̶i̶m̶o̶n̶b̶o̶r̶g̶/̶p̶h̶x̶_̶t̶e̶s̶t̶)̶,̶ ̶a̶n̶d̶ ̶i̶s̶ ̶n̶o̶t̶ ̶p̶u̶b̶l̶i̶s̶h̶e̶d̶ ̶t̶o̶ ̶h̶e̶x̶.̶ ̶Y̶o̶u̶ ̶c̶a̶n̶ ̶a̶d̶d̶ ̶i̶t̶ ̶t̶o̶ ̶y̶o̶u̶r̶ ̶d̶e̶p̶s̶ ̶w̶i̶t̶h̶ ̶̶{̶:̶p̶h̶x̶_̶t̶e̶s̶t̶,̶ ̶g̶i̶t̶:̶ ̶"̶h̶t̶t̶p̶s̶:̶/̶/̶g̶i̶t̶h̶u̶b̶.̶c̶o̶m̶/̶m̶s̶i̶m̶o̶n̶b̶o̶r̶g̶/̶p̶h̶x̶_̶t̶e̶s̶t̶"̶,̶ ̶o̶n̶l̶y̶:̶ ̶[̶:̶d̶e̶v̶,̶ ̶:̶t̶e̶s̶t̶]̶}̶
̶.̶ This is available on hex, and you can addit to your project with {:phx_test, "~> 0.1.0", only: [:dev, :test]}
. So far this has been sort of an experiment for my own learning and enjoyment, and I may put it down if there’s not much interest from the Elixir community, so I’m curious:
- Is doing something like this even a good idea?
- Does it seem useful enough in the real world to keep developing it?
- Is there anything like this already?
- Are there any gotchas I’m not aware of?
- Can you think of anything that would make this better if I continue working on it?
Thanks for reading!