Skip to content

Commit d82e8dd

Browse files
authored
Also give parameter attribution for other kinds of failures (#44)
Followup to #41 to handle errors in tests that are not assertion errors.
1 parent be313c4 commit d82e8dd

4 files changed

Lines changed: 135 additions & 12 deletions

File tree

lib/parameterized_test.ex

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,9 @@ defmodule ParameterizedTest do
133133
test "#{full_test_name}", unquote(context_ast) do
134134
try do
135135
unquote(blocks)
136-
rescue
137-
e in ExUnit.AssertionError ->
138-
ParameterizedTest.Backtrace.add_test_context(e, __STACKTRACE__, @param_test_context)
136+
catch
137+
category, reason ->
138+
ParameterizedTest.Backtrace.add_test_context({category, reason}, __STACKTRACE__, @param_test_context)
139139
end
140140
end
141141
end
@@ -195,9 +195,9 @@ defmodule ParameterizedTest do
195195
feature "#{@full_test_name}", unquote(context_ast) do
196196
try do
197197
unquote(blocks)
198-
rescue
199-
e in ExUnit.AssertionError ->
200-
ParameterizedTest.Backtrace.add_test_context(e, __STACKTRACE__, @param_test_context)
198+
catch
199+
category, reason ->
200+
ParameterizedTest.Backtrace.add_test_context({category, reason}, __STACKTRACE__, @param_test_context)
201201
end
202202
end
203203
end

lib/parameterized_test/backtrace.ex

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,17 @@ defmodule ParameterizedTest.Backtrace do
22
@moduledoc false
33
alias ParameterizedTest.Parser
44

5-
@spec add_test_context(ExUnit.AssertionError.t(), [tuple()], Parser.context()) :: no_return()
6-
def add_test_context(%ExUnit.AssertionError{} = e, bt, context) do
7-
reraise e, augment_backtrace(bt, context)
5+
@spec add_test_context({atom(), term()}, [tuple()], Parser.context()) :: no_return()
6+
def add_test_context({:error, %{__exception__: true} = exception}, bt, context) do
7+
reraise exception, augment_backtrace(bt, context)
8+
end
9+
10+
def add_test_context({:error, payload}, bt, context) do
11+
reraise ErlangError.normalize(payload, bt), augment_backtrace(bt, context)
12+
end
13+
14+
def add_test_context({kind, payload}, bt, context) do
15+
reraise RuntimeError.exception("#{kind}: #{inspect(payload)}"), augment_backtrace(bt, context)
816
end
917

1018
defp augment_backtrace(bt, context) do

test/parameterized_test/backtrace_test.exs

Lines changed: 96 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ defmodule ParameterizedTest.BacktraceTest do
2121

2222
try do
2323
assert not should_fail?
24-
rescue
25-
e in ExUnit.AssertionError ->
24+
catch
25+
category, reason ->
2626
try do
27-
ParameterizedTest.Backtrace.add_test_context(e, __STACKTRACE__, context)
27+
ParameterizedTest.Backtrace.add_test_context({category, reason}, __STACKTRACE__, context)
2828
rescue
2929
ExUnit.AssertionError ->
3030
assert [failing_line, parameter_line | _] = __STACKTRACE__
@@ -44,6 +44,20 @@ defmodule ParameterizedTest.BacktraceTest do
4444
end
4545
end
4646

47+
test "translates Erlang errors" do
48+
assert_raise ArithmeticError, fn ->
49+
context = [file: __ENV__.file, min_line: __ENV__.line, raw: "| true |"]
50+
ParameterizedTest.Backtrace.add_test_context({:error, :badarith}, [], context)
51+
end
52+
end
53+
54+
test "turns other errors into RuntimeErrors" do
55+
assert_raise RuntimeError, fn ->
56+
context = [file: __ENV__.file, min_line: __ENV__.line, raw: "| true |"]
57+
ParameterizedTest.Backtrace.add_test_context({:timeout, {GenServer, :call, [self(), :slow_call, 0]}}, [], context)
58+
end
59+
end
60+
4761
@tag failure_with_backtrace: true
4862
param_test "points to line #{__ENV__.line + 4} when a test fails",
4963
"""
@@ -149,4 +163,83 @@ defmodule ParameterizedTest.BacktraceTest do
149163
} do
150164
assert not gets_free_shipping?
151165
end
166+
167+
@tag failure_with_backtrace: true
168+
param_test "handles other exceptions, attribute to line #{__ENV__.line + 4}",
169+
"""
170+
| should_fail? |
171+
| false |
172+
| true |
173+
""",
174+
%{should_fail?: should_fail?} do
175+
if should_fail? do
176+
raise "test failed"
177+
else
178+
assert 1 == 1
179+
end
180+
end
181+
182+
@tag failure_with_backtrace: true
183+
param_test "handles code errors, attribute to line #{__ENV__.line + 4}",
184+
"""
185+
| should_fail? |
186+
| false |
187+
| true |
188+
""",
189+
%{should_fail?: should_fail?} do
190+
if should_fail? do
191+
assert Code.eval_string("nil + 1") == 2
192+
else
193+
assert 1 == 1
194+
end
195+
end
196+
197+
defmodule SlowGenServer do
198+
@moduledoc false
199+
@behaviour GenServer
200+
201+
def start_link(opts \\ []), do: GenServer.start_link(__MODULE__, opts, name: __MODULE__)
202+
203+
@impl GenServer
204+
def init(_), do: {:ok, []}
205+
206+
def slow_call(pid) do
207+
GenServer.call(pid, :slow_call, 0)
208+
end
209+
210+
@impl GenServer
211+
def handle_call(:slow_call, _from, state) do
212+
:timer.sleep(1000)
213+
{:reply, :ok, state}
214+
end
215+
end
216+
217+
@tag failure_with_backtrace: true
218+
param_test "handles non-assertion errors too, attribute to line #{__ENV__.line + 4}",
219+
"""
220+
| should_fail? |
221+
| false |
222+
| true |
223+
""",
224+
%{should_fail?: should_fail?} do
225+
if should_fail? do
226+
{:ok, pid} = SlowGenServer.start_link()
227+
SlowGenServer.slow_call(pid)
228+
end
229+
end
230+
231+
@tag skip: true
232+
@tag failure_with_backtrace: true
233+
param_feature "handles non-assertion errors in features, attribute to line #{__ENV__.line + 4}",
234+
"""
235+
| should_fail? |
236+
| false |
237+
| true |
238+
""",
239+
%{should_fail?: should_fail?} do
240+
if should_fail? do
241+
{:ok, pid} = SlowGenServer.start_link()
242+
SlowGenServer.slow_call(pid)
243+
end
244+
end
152245
end

test/parameterized_test_test.exs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,17 @@ defmodule ParameterizedTestTest do
354354
""" do
355355
flunk("This test should not run")
356356
end
357+
358+
param_test "applies param_test: true to all parameterized tests",
359+
"""
360+
| text | url |
361+
|----------|----------------------|
362+
| "GitHub" | "https://github.com" |
363+
| "Google" | "https://google.com" |
364+
""",
365+
context do
366+
assert context[:param_test] == true
367+
end
357368
end
358369

359370
defmodule ParameterizedTestTest.WallabyTest do
@@ -373,4 +384,15 @@ defmodule ParameterizedTestTest.WallabyTest do
373384
|> visit(url)
374385
|> assert_has(Wallaby.Query.text(text, minimum: 1))
375386
end
387+
388+
param_feature "applies param_feature: true to all parameterized tests",
389+
"""
390+
| text | url |
391+
|----------|----------------------|
392+
| "GitHub" | "https://github.com" |
393+
| "Google" | "https://google.com" |
394+
""",
395+
context do
396+
assert context[:param_test] == true
397+
end
376398
end

0 commit comments

Comments
 (0)