TestAsync

Make tests inside your ExUnit case to run async.

Installation

Available in Hex, the package can be installed by adding test_async to your list of dependencies in mix.exs:

def deps do
[{:test_async, "~> 0.1.0", only: :test, runtime: false}]
end

Intro

As you might already know, ExUnit lets you define async test cases by providing an async: true option, like this:

defmodule App.FineTest do
use ExUnit.Case, async: true
test "one" do
IO.inspect :one
end
test "two" do
IO.inspect :two
end
end
defmodule App.OtherTest do
use ExUnit.Case, async: true
test "three" do
IO.inspect :three
end
end

As described by the ExUnit documentation

async: true, runs the test case concurrently with other test cases. The individual tests within each test case are still run serially

That means, one and two will still be run one after the other.

If you'd want those two to be run concurrently, you'd have to create a new test case module for each.

This is exactly what TestAsync does, by providing a tiny macro test macro that will turn your ExUnit case tests into async cases.

Usage

Just use TestAsync !

defmodule App.FineTest do
use ExUnit.Case
use TestAsync
test "one" do
IO.inspect :one
end
test "two" do
IO.inspect :two
end
end

Gotchas

Current module

If you use __MODULE__ on a test body, it will be the name of the generated case module and not the one of the parent module.

defmodule App.NamedTest do
use ExUnit.Case
test "one" do
assert __MODULE__ == App.NamedTest.OneTest
end
end

Private functions

Private functions defined on the parent module cannot be seen inside the generated async modules.

defmodule App.SomeTest do
use ExUnit.Case
use TestAsync
defp hidden, do: :ninja
test "cant be seen" do
assert hidden() # compile error
end
end

However you can give use TestAsync a do block, which will be turned into a shared ExUnit.CaseTemplate.

defmodule App.NinjaTest do
use ExUnit.Case
use TestAsync do
defp hidden, do: :ninja
end
test "can be seen" do
assert hidden()
end
end