msimonborg

msimonborg

Phx_test - Quickly create and configure Phoenix test apps for library developers

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 :slight_smile:

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!

Most Liked

nikokozak

nikokozak

Hey @msimonborg this is a really interesting project, and was wondering if there’s any way I could maybe contribute to it. I’ve run into this problem again and again, and have yet to find an easy/organic way around having to set up new phoenix instances and inject tests into them in order to make sure my library works (until I came across this).

Where Next?

Popular in Libraries Top

marcuslankenau
I feel kind of stuck with the absence of a proper xml library for Elixir. Currently I use SweetXML which was ok for me more or less to pa...
New
Crowdhailer
Raxx is an alternative to Plug and is inspired by projects such as Rack(Ruby) and Ring(Clojure). 1.0-rc.1 is now available. To use it re...
New
archan937
It is a well-know topic within the Elixir community: “To mock or not to mock? :)” Every alchemist probably has his / her own opinion con...
New
josevalim
EDIT: since Ecto 3.0 final version is out, this post was amended to use the final versions in the instructions below. Hi everyone, We a...
New
woutdp
Hi! I wanted to introduce my latest project LiveSvelte. It allows you to render Svelte inside LiveView with end-to-end reactivity. It’s ...
New
Antrater
Hi everyone! I’m thrilled to announce a huge thing. We have been developing Elixir Moon Design System for quite a while. We are finally ...
New
wmnnd
Hi there, for my project DBLSQD, I needed a file storage solution that is a bit more flexible than Arc. Because I thought others might f...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 42633 214
New
vic
Expat is a tiny experiment I did for extracting patterns and being able to reuse them (compose and share patterns between elixir librarie...
New
wojtekmach
Hey everyone! Req is an HTTP client for Elixir that I’ve been working on for quite some time. There is already a lot of HTTP clients out...
New

Other popular topics Top

vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
malloryerik
Hi, this is for people who, like me, have had some friction using .html.heex templates in VSCode. The solution seems to be, in a hyphena...
New
polypush135
As many of you may have realized by now (sorry for all the posts here) I’ve been working on a db problem where I’m trying to aggregate a ...
New
script
If I have a string “1000 cfu/ml” . I want to remove the characters and / and space . So the string is like this "1000" What is the ...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New

Sub Categories:

We're in Beta

About us Mission Statement