ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe blocks are forbidden, and instead developers should “build on top of named setups”. The following example used:
defmodule UserManagementTest do use ExUnit.Case, async: true describe "when user is logged in and is an admin" do setup [:log_user_in, :set_type_to_admin] test ... end describe "when user is logged in and is a manager" do setup [:log_user_in, :set_type_to_manager] test ... end defp log_user_in(context) do # ... end end
For comparsion, here’s how I might lay out the same test using RSpec:
RSpec.describe UserManagement, type: :model do describe "some method" do context "when user is logged in" do before do .. end context "when user is an admin" do before do ... end it ... end context "when user is a manager" do before do ... end it ... end end end end
The reasoning for ExUnit way is solid - it’s easier to glance at a single describe block in isolation and understand exactly what is going on. However, coming from RSpec, the ability the lay out multiple contexts as described above is useful for covering all scenarios. In particular, if there’s three or four different contexts that need to be checked, including different combinations of each, having a hierarchy can help to lay out all of the different pathways through the code. If the contexts are keep flat, we would end up with very long describe/context strings, e.g. “when user is logged in and user is an admin and user is an author and user is a publisher”.
Since ExUnit doesn’t support nested describe/context blocks, what are some alternative strategies to describe these more complex sets of contexts?