Parameterizing an entire test case?

I have a test case with a setup and multiple tests. I want to run the exact same tests a couple times, changing a variable each time. In Rspec, this is trivial with let and shared_examples. ExUnit.Parameterized looks like it applies to individual test cases but not to the entire set of tests. What’s the right way to accomplish this in ExUnit?

I’m fairly new to Elixir for what that’s worth.

The way I usually do this is like this:

%{1 => 2, 2 => 3}
|> Enum.each(fn {input, exp} ->
  test "#{input} increased by one is #{exp}" do
    assert unquote(exp) = 1 + unquote(input)
  end
end)

For some more complex input values, you might need to unquote(Macro.escape(…)), but you’ll figure this one out as soon as ecto barfs at you because its unable to unquote something.

2 Likes

Depending on your inputs you might also want to just put these all in a single test

test "input increases by one" do
  %{1 => 2, 2 => 3}
  |> Enum.each(fn {input, exp} ->
    assert exp == 1 + input
  end)
end

Although you could also extend @NobbZ approach to all the tests in the file by including multiple test declarations inside the Enum.each

I do not like having many asserts in a single test.

Especially for such things. If you to a --trace or otherwise try to get a list of slow test, than very simple tests with a lot of different input might appear as slow tests, but in fact its not one slow test, but thousand fast ones.

But I think this is really a matter of personal taste.

It might also make sense to assign them to a local variable first in those cases.

I agree about the amount of asserts per test: Another problem is that later asserts will not be tested against once the first one fails.