Skip to content

Commit

Permalink
Raise AssertionError instead of RuntimeError (#13)
Browse files Browse the repository at this point in the history
Currently, assertions `assert_has` and `refute_has` raise `RuntimeError`

```
  1) test index shows empty states (Manage.PageLiveTest)
     apps/manage/test/manage/live/page_test.exs:6
     ** (RuntimeError) Could not find any elements with selector "span#bar".

     code: |> assert_has("span#bar", "foo")
     stacktrace:
       (phoenix_test 0.2.1) lib/phoenix_test/assertions.ex:17: PhoenixTest.Assertions.assert_has/3
       test/manage/live/page_test.exs:9: (test)
```

This works, but it's more common for assertion helpers to raise
`ExUnit.AssertionError` instead, as it signals that
there is something wrong with what the test author is asserting vs.
something wrong with the setup as such.

This PR introduces `AssertionError` to the `Assertions` module, and only
there. This is how output of the same test
looks like:

```
  1) test index shows empty states (Manage.PageLiveTest)
     apps/manage/test/manage/live/page_test.exs:6
     Could not find any elements with selector "span#bar".

     code: |> assert_has("span#bar", "foo")
     stacktrace:
       (phoenix_test 0.2.1) lib/phoenix_test/assertions.ex:18: PhoenixTest.Assertions.assert_has/3
       test/manage/live/page_test.exs:9: (test)
```
  • Loading branch information
soundmonster authored Feb 8, 2024
1 parent 5c1c0a8 commit 117bc59
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 50 deletions.
39 changes: 22 additions & 17 deletions lib/phoenix_test/assertions.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ defmodule PhoenixTest.Assertions do
@moduledoc false

import ExUnit.Assertions
alias ExUnit.AssertionError

alias PhoenixTest.Query

Expand All @@ -14,18 +15,20 @@ defmodule PhoenixTest.Assertions do
assert true

{:not_found, []} ->
raise """
Could not find any elements with selector #{inspect(selector)}.
"""
raise AssertionError,
message: """
Could not find any elements with selector #{inspect(selector)}.
"""

{:not_found, elements_matched_selector} ->
raise """
Could not find element with text #{inspect(text)}.
raise AssertionError,
message: """
Could not find element with text #{inspect(text)}.
Found other elements matching the selector #{inspect(selector)}:
Found other elements matching the selector #{inspect(selector)}:
#{format_found_elements(elements_matched_selector)}
"""
#{format_found_elements(elements_matched_selector)}
"""
end

session
Expand All @@ -40,20 +43,22 @@ defmodule PhoenixTest.Assertions do
refute false

{:found, element} ->
raise """
Expected not to find an element.
raise AssertionError,
message: """
Expected not to find an element.
But found an element with selector #{inspect(selector)} and text #{inspect(text)}:
But found an element with selector #{inspect(selector)} and text #{inspect(text)}:
#{format_found_element(element)}
"""
#{format_found_element(element)}
"""

{:found_many, elements} ->
raise """
Expected not to find an element.
raise AssertionError,
message: """
Expected not to find an element.
But found #{Enum.count(elements)} elements with selector #{inspect(selector)} and text #{inspect(text)}:
"""
But found #{Enum.count(elements)} elements with selector #{inspect(selector)} and text #{inspect(text)}:
"""
end

session
Expand Down
86 changes: 53 additions & 33 deletions test/phoenix_test/assertions_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ defmodule PhoenixTest.AssertionsTest do
use ExUnit.Case, async: true

import PhoenixTest
alias ExUnit.AssertionError

setup do
%{conn: Phoenix.ConnTest.build_conn()}
Expand Down Expand Up @@ -55,7 +56,7 @@ defmodule PhoenixTest.AssertionsTest do

msg = ~r/Could not find any elements with selector "#nonexistent-id"/

assert_raise RuntimeError, msg, fn ->
assert_raise AssertionError, msg, fn ->
conn |> assert_has("#nonexistent-id", "Main page")
end
end
Expand All @@ -65,15 +66,17 @@ defmodule PhoenixTest.AssertionsTest do
} do
conn = visit(conn, "/page/index")

msg = """
Could not find element with text "Super page".
msg =
"""
Could not find element with text "Super page".
Found other elements matching the selector "h1":
Found other elements matching the selector "h1":
<h1> with content "Main page"
"""
<h1> with content "Main page"
"""
|> ignore_whitespace()

assert_raise RuntimeError, msg, fn ->
assert_raise AssertionError, msg, fn ->
conn |> assert_has("h1", "Super page")
end
end
Expand All @@ -83,25 +86,27 @@ defmodule PhoenixTest.AssertionsTest do
} do
conn = visit(conn, "/page/index")

msg = """
Could not find element with text "Frodo".
msg =
"""
Could not find element with text "Frodo".
Found other elements matching the selector "#multiple-items":
Found other elements matching the selector "#multiple-items":
<ul> with content:
<li>
Aragorn
</li>
<li>
Legolas
</li>
<li>
Gimli
</li>
<ul> with content:
<li>
Aragorn
</li>
<li>
Legolas
</li>
<li>
Gimli
</li>
"""
"""
|> ignore_whitespace()

assert_raise RuntimeError, msg, fn ->
assert_raise AssertionError, msg, fn ->
conn |> assert_has("#multiple-items", "Frodo")
end
end
Expand Down Expand Up @@ -139,31 +144,46 @@ defmodule PhoenixTest.AssertionsTest do
test "raises an error if one element is found", %{conn: conn} do
conn = visit(conn, "/page/index")

msg = """
Expected not to find an element.
msg =
"""
Expected not to find an element.
But found an element with selector "#title" and text "Main page":
But found an element with selector "#title" and text "Main page":
<h1> with content "Main page"
"""
<h1> with content "Main page"
"""
|> ignore_whitespace()

assert_raise RuntimeError, msg, fn ->
assert_raise AssertionError, msg, fn ->
conn |> refute_has("#title", "Main page")
end
end

test "raises an error if multiple elements are found", %{conn: conn} do
conn = visit(conn, "/page/index")

msg = """
Expected not to find an element.
msg =
"""
Expected not to find an element.
But found 2 elements with selector ".multiple_links" and text "Multiple links":
"""
But found 2 elements with selector ".multiple_links" and text "Multiple links":
"""
|> ignore_whitespace()

assert_raise RuntimeError, msg, fn ->
assert_raise AssertionError, msg, fn ->
conn |> refute_has(".multiple_links", "Multiple links")
end
end
end

# converts a multi-line string into a whitespace-forgiving regex
defp ignore_whitespace(string) do
string
|> String.split("\n")
|> Enum.map(&String.trim/1)
|> Enum.reject(fn s -> s == "" end)
|> Enum.map(fn s -> "\\s*" <> s <> "\\s*" end)
|> Enum.join("\n")
|> Regex.compile!([:dotall])
end
end

0 comments on commit 117bc59

Please sign in to comment.