I think a little context for this conversation is important here.
There's a little bit of urgency to me because we need some way to control
1) all of the ceremony inherent in setup
2) the duplication in setup
We're using Elixir in production now, and one of the first things we did was to build a solution that allowed us to solve this problem. I think others are starting to do the same. If we don't start to address the pain points inherent in exunit, everyone is going to be building and promoting their own testing framework.
Personally, this is where I am. If we get an Elixir alternative relatively soon, we'll use it. If we have to wait too long, we'll just evolve what we have, and others will do the same, and it will be a shame.
Given that backdrop, José and I have been talking about alternatives.
We use, and are happy with, a test case that looks like this:
with "a connection" do
setup(context)...
end
test...
test...
with "a logged in user" do
setup(context)...
test...
test...
end
end
and we're comfortable. It allows us to group and name logical tests, and it lets us nest contexts through the setups. José didn't like that as much because people can take nested contexts too far. So we brainstormed some and came up with the idea of named setup functions. That lets me have many first level setups, like this:
setup context |> log_in(:joe) |> create_post |> ...
... tests with a logged in user
setup context |> log_in(:admin) |> create_post |> ...
... tests with a logged in admin
setup context |> create_post |> ...
... tests with a logged out user
defsetup login(context, username) do... #(or maybe just def)
...
It lets me quickly organize my tests, and thought the pipe doesn't work exactly like Elixir does it is a useful visual representation. It is slightly better than nested contexts, because I don't have to organize my setups in a strict tree.
In general, that code is beautiful to read; I intuitively understand what it does, and I have no problems with macros that allow us to maintain a mental model without maintaining precise semantics if there are very good reasons for doing so.
You can also see potential here. Since things compose, we could eventually use a similar strategy for integration tests. We could have module attributes (or just additional string arguments to setups) that further describe what a group of tests is doing so you'd be able to tell what failed without consulting the tests.
The cost is that the macro makes use of the pipe symbol to communicate something that is almost the same as composition, but not quite. As far as my team is concerned, we read and write tests as often as we do any other development task.
But we have to have some common place to start. It also will show that exunit is evolving, and it will be less likely that the Elixir testing situation fragments and degenerates like testing communities just about everywhere else.
All this is to say that I am not married to the pipe syntax, but I am married to *something*, in release 1.1, that helps me control duplicate setup code and the surrounding ceremony that makes my tests much harder to read., write, and maintain.
Hope this provides a little context to this proposal.
-bt