I’ve been playing round with test fixtures using setup_all, and I’m considering opening a pull request which includes a few more concrete examples.
The specific behavior that I found to be a bit of a secret is that your test statements can receive values from the setup_all blocks (!!!). In addition to being a bit of a secret bit of functionality, I also had some confusion as to why the setup_all block could return either a map OR a tuple (with a map), and the test statement receives only the map. This is the type of “magic” or hidden functionality that can make code difficult to understand, so I would like to ask for some insight from the forum members on this topic.
Would adding the following as ## Examples in the documentation be useful?
defmodule ExampleATest do
use ExUnit.Case
setup_all do
%{is_a_map: true}
end
test "this function receives the output of the setup_all callback", value do
assert true == value[:is_a_map]
end
end
defmodule ExampleBTest do
use ExUnit.Case
setup_all do
[keyword: true]
end
test "keyword lists are also allowed", value do
assert true == value[:keyword]
end
end
defmodule ExampleCTest do
use ExUnit.Case
setup_all do
{:ok, %{is_a_map: true}}
end
test "surprisingly, if an :ok tuple is returned, tests only receive the value", value do
assert true == value[:is_a_map]
end
end
Yeah, I read that but I didn’t understand much of it from the examples given. “Your documentation has too many examples” said no developer ever. I’ll put together a PR and see what comes of it. Thanks!
defmodule EdnoTest do
use ExUnit.Case
setup_all do
{:ok, setup_all: :rand.uniform(100)}
end
setup do
{:ok, setup: :rand.uniform(100)}
end
test "1", context do
IO.inspect Map.take(context, [:setup_all, :setup])
end
test "2", context do
IO.inspect Map.take(context, [:setup_all, :setup])
end
end
That’s a great example! Worthy of being included in the docs.
What’s tripping me is that the docs do not have examples as clear as that. I know I am an educator, so my standards for documentation may be high, but I feel the current docs could help reduce mental friction and clarify this feature more quickly by including more examples. Explanations are a nice-to-have; examples are paramount.
Specifically:
The docs nowhere mention the notion of a Test Fixture, and that’s really what these functions are relevant to. Other languages/frameworks refer to such functions as fixtures, so the mere act of name-dropping that term will help the light-bulb go off for some people.
The examples of the context variable could be more clear (e.g. like yours).
I haven’t seen a clear example of how/why you can return a tuple OR a map and the context comes through the same. That’s kind of a weird bit of unseen macro “magic” that is rare in the functional world.
I’m working on the PR to include some clarifications to the existing docs.
I did make the mind-mapping from the previous TDD terminology I was familiar with, and connected it to ExUnit myself. But I agree that it should be explicit in the docs.
Sounds like you can use your educator / copywriter skills to help improve the docs then.