README.md

# TestAsync
<a href="https://travis-ci.org/vic/test_async"><img src="https://travis-ci.org/vic/test_async.svg"></a>

Make tests inside your ExUnit case to run async.

## Installation

[Available in Hex](https://hex.pm/package/test_async), the package can be installed
by adding `test_async` to your list of dependencies in `mix.exs`:

```elixir
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:

```elixir
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](https://hexdocs.pm/ex_unit/ExUnit.html) 


> `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` !

```elixir
defmodule App.FineTest do
  use ExUnit.Case
  use TestAsync

  test "one" do
    IO.inspect :one
  end

  test "two" do
    IO.inspect :two
  end
end
```

[More examples as tests](https://github.com/vic/test_async/blob/master/test/)

## 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.

```elixir
defmodule App.NamedTest do
  use ExUnit.Case

  test "one" do
    assert __MODULE__ == App.NamedTest.OneTest
  end
end
```

#### Setup functions

`setup` and `setup_all` are supported but only if they are given a
function name. And `setup_all` is run for every test instead of just
once as now every test was turned into its own test case.

#### Private functions 

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

```elixir
defmodule App.SomeTest do
  use ExUnit.Case
  use TestAsync

  defp hidden, do: :ninja

  test "cant be seen" do
    assert hidden() # compile error
  end
end
```

#### Shared case template

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

```elixir
defmodule App.NinjaTest do
  use ExUnit.Case

  use TestAsync do
    defp hidden, do: :ninja
  end

  test "can be seen" do
    assert hidden()
  end
end
```