%{ title: "How We Test LiveView at Scale", author: "Carlos Rivera", tags: ~w(elixir liveview testing), description: "Our testing strategy for 200+ LiveView modules" } --- *This is a sample blog post, generated to show what blogex can do.* With over 200 LiveView modules in our codebase, we needed a testing strategy that was both fast and reliable. Here's what we landed on. ## The three-layer approach We test LiveViews at three levels: 1. **Unit tests** for the assign logic — pure functions, no rendering 2. **Component tests** for individual function components using `render_component/2` 3. **Integration tests** for full page flows using `live/2` The key insight is that most bugs live in the assign logic, not in the templates. By extracting assigns into pure functions, we can test the interesting bits without mounting a LiveView at all. ```elixir defmodule MyAppWeb.DashboardLive do use MyAppWeb, :live_view # Pure function — easy to test def compute_metrics(raw_data, date_range) do raw_data |> Enum.filter(&in_range?(&1, date_range)) |> Enum.group_by(& &1.category) |> Enum.map(fn {cat, items} -> %{category: cat, count: length(items), total: Enum.sum_by(items, & &1.value)} end) end end # In the test file test "compute_metrics groups and sums correctly" do data = [ %{category: "sales", value: 100, date: ~D[2026-03-01]}, %{category: "sales", value: 200, date: ~D[2026-03-02]}, %{category: "support", value: 50, date: ~D[2026-03-01]} ] result = DashboardLive.compute_metrics(data, {~D[2026-03-01], ~D[2026-03-31]}) assert [ %{category: "sales", count: 2, total: 300}, %{category: "support", count: 1, total: 50} ] = Enum.sort_by(result, & &1.category) end ``` ## Speed matters Our full test suite runs in under 90 seconds on CI. The secret is `async: true` everywhere and avoiding database writes in unit tests. We use `Mox` for external service boundaries and `Ecto.Adapters.SQL.Sandbox` only for integration tests. ## What we'd do differently If starting over, we'd adopt property-based testing with `StreamData` earlier. Several production bugs would have been caught by generating edge-case assigns rather than hand-writing examples.