Hello, all! I want to share a pattern that I have found useful and get your feedback. I am relatively new to LiveView, so I am doing so humbly at risk of beginners naivety.
In short, as I began writing tests of LiveViews, I found it difficult to keep the different parts of the test state organized in my mind. Those being: 1) the conn
, 2) the “live”, and 3) the “html” doc that is often asserted against. This would distract me from the actual interactions that the test is meant to describe.
Here is a brief example (contrived, but hopefully realistic):
import Phoenix.LiveViewTest
test "live view", %{conn: conn} do
{:ok, live, html} = live(conn, "/")
assert html =~ "New"
assert live |> element("a.new") |> render_click() =~ "Enter new"
assert_patch(live, "/new")
{:ok, _, html} = live |> form(".form", @attrs) |> render_submit() |> follow_redirect(conn)
assert html =~ "success"
end
By my judgement, this is pretty typical of LiveView tests. In the test, the value that is being handled switches between the conn (starting the view and following redirect), the live view (clicking the link and submitting the form) and the HTML docs (asserting initial page content and changes as links and forms are interacted with). The clicks and forms I found particularly confusing, because the data of focus changes from live view to HTML through the pipeline. Ultimately I just want to focus on the user interactions.
That’s where some helper functions come in. Essentially their purpose is to bundle this context together and make everything a pipeline so that the reader is relieved of mentally juggling the state.
Here’s the same example refactoring with these helpers:
use Iamvery.Phoenix.LiveView.TestHelpers
test "live view", %{conn: conn} do
start(conn, "/")
|> assert_html("New")
|> click("a.new")
|> assert_html("Enter new")
|> assert_path("/new")
|> submit_form(".form", @attrs)
|> assert_html("success")
end
As you can see, I’ve bundled these up (for now) as a part of a utility package that I maintain, but if they’re well-received, I could see them becoming a part of the LiveView package itself. With some more work, of course, they’re not meant to be a complete set at this time.
Here is a link to the package source and a blog post I put together as well:
Let me know what you think!