Testing Guide
View SourceLiveVue provides a robust testing module LiveVue.Test
that makes it easy to test Vue components within your Phoenix LiveView tests.
Overview
Testing LiveVue components differs from traditional Phoenix LiveView testing in a key way:
- Traditional LiveView testing uses
render_component/2
to get final HTML - LiveVue testing provides helpers to inspect the Vue component configuration before client-side rendering
Testing Configuration
For comprehensive testing, you should disable props diffing in your test environment to ensure LiveVue.Test.get_vue/2
always returns complete props data:
# config/test.exs
config :live_vue,
enable_props_diff: false
When props diffing is enabled (the default), LiveVue only sends changed properties to optimize performance. However, during testing, you typically want to inspect the complete component state rather than just the incremental changes. Disabling diffing ensures that all props are always available for testing assertions.
This configuration should be set globally for the test environment rather than per-component, as it affects the behavior of the testing helpers.
Basic Component Testing
Let's start with a simple component test:
defmodule MyAppWeb.CounterTest do
use MyAppWeb.ConnCase
alias LiveVue.Test
test "renders counter component with initial props", %{conn: conn} do
{:ok, view, _html} = live(conn, "/counter")
vue = Test.get_vue(view)
assert vue.component == "Counter"
assert vue.props == %{"count" => 0}
end
end
The get_vue/2
function returns a map containing:
:component
- Vue component name:id
- Unique component identifier:props
- Decoded props:handlers
- Event handlers and operations:slots
- Slot content:ssr
- SSR status:class
- CSS classes
Testing Multiple Components
When your view contains multiple Vue components, you can specify which one to test:
# Find by component name
vue = Test.get_vue(view, name: "UserProfile")
# Find by ID
vue = Test.get_vue(view, id: "profile-1")
Example with multiple components:
def render(assigns) do
~H"""
<div>
<.vue id="profile-1" name="John" v-component="UserProfile" />
<.vue id="card-1" name="Jane" v-component="UserCard" />
</div>
"""
end
test "finds specific component" do
html = render_component(&my_component/1)
# Get UserCard component
vue = Test.get_vue(html, name: "UserCard")
assert vue.props == %{"name" => "Jane"}
# Get by ID
vue = Test.get_vue(html, id: "profile-1")
assert vue.component == "UserProfile"
end
Testing Event Handlers
You can verify event handlers are properly configured:
test "component has correct event handlers" do
vue = Test.get_vue(render_component(&my_component/1))
assert vue.handlers == %{
"click" => JS.push("click", value: %{"abc" => "def"}),
"submit" => JS.push("submit")
}
end
Testing Slots
LiveVue provides tools to test both default and named slots:
def component_with_slots(assigns) do
~H"""
<.vue v-component="WithSlots">
Default content
<:header>Header content</:header>
<:footer>Footer content</:footer>
</.vue>
"""
end
test "renders slots correctly" do
vue = Test.get_vue(render_component(&component_with_slots/1))
assert vue.slots == %{
"default" => "Default content",
"header" => "Header content",
"footer" => "Footer content"
}
end
Important notes about slots:
- Use
<:inner_block>
instead of<:default>
for default content - Slots are automatically Base64 encoded in the HTML
- The test helper decodes them for easier assertions
Testing SSR Configuration
Verify Server-Side Rendering settings:
test "respects SSR configuration" do
vue = Test.get_vue(render_component(&my_component/1))
assert vue.ssr == true
# Or with SSR disabled
vue = Test.get_vue(render_component(&ssr_disabled_component/1))
assert vue.ssr == false
end
Testing CSS Classes
Check applied styling:
test "applies correct CSS classes" do
vue = Test.get_vue(render_component(&my_component/1))
assert vue.class == "bg-blue-500 rounded"
end
Integration Testing
For full integration tests, you should use headless browser to render components. Currently this guide is a work in progress.
Best Practices
Component Isolation
- Test Vue components in isolation when possible
- Use
render_component/1
for focused tests
Clear Assertions
- Test one aspect per test
- Use descriptive test names
- Assert specific properties rather than entire component structure
Integration Testing
- Test full component interaction in LiveView context
- Verify both server and client-side behavior
- Test error cases and edge conditions
Maintainable Tests
- Use helper functions for common assertions
- Keep test setup minimal and clear
- Document complex test scenarios