Skip to content

Commit 1156937

Browse files
committed
Improve readme
1 parent 77cf487 commit 1156937

File tree

2 files changed

+18
-14
lines changed

2 files changed

+18
-14
lines changed

README.md

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
11
# AsyncTest
22

3-
Makes tests within a single module run asynchronously.
3+
Makes tests within a single module (ExUnit Case) run asynchronously.
44

5-
Just `import #{inspect(__MODULE__)}` and replace
6-
`test` with `async_test`. It should be a drop-in
7-
replacement.
5+
Just `import AsyncTest` and replace `test`s with `async_test`s. It should be a drop-in replacement.
86

9-
#{inspect(__MODULE__)} works in the following way:
7+
AsyncTest works in the following way:
108
- create a public function instead of a test
119
- create a new module with a single test that calls that function
12-
- copy all `@tags` to the newly created module
13-
- handle `setup` and `setup_all` similarly to `test`s - the `setup`
14-
in the new module calls a public function from the original module
10+
- mimic `@tags`, `setup`, `setup_all`, and `describe` structure in the new module
1511
- ensure `setup_all` is called only once - store its result in an
1612
`Agent` and retrieve it when needed
1713

@@ -22,12 +18,12 @@ Add `async_test` to deps:
2218
```elixir
2319
def deps do
2420
[
25-
{:async_test, github: "software-mansion-labs/elixir_async_test"}
21+
{:async_test, github: "software-mansion-labs/elixir_async_test", only: :test}
2622
]
2723
end
2824
```
2925

30-
In tests, `import AsyncTest` and replace `test` with `async_test`:
26+
In tests, `import AsyncTest` and replace `test`s with `async_test`s:
3127

3228
```diff
3329
defmodule MyTest do
@@ -39,10 +35,19 @@ In tests, `import AsyncTest` and replace `test` with `async_test`:
3935
+ async_test "my test" do
4036
assert true
4137
end
38+
end
4239
```
4340

4441
Now, all the `async_test`s will run asynchronously regardless of the module.
4542

43+
## Motivation
44+
45+
TL;DR Async tests in a single module may be harmful, thus ExUnit doesn't support them, but in particular cases they're beneficial.
46+
47+
ExUnit always runs tests in a single module synchronously (except of [parameterized tests](https://hexdocs.pm/ex_unit/ExUnit.Case.html#module-parameterized-tests)). [This PR](https://github.com/elixir-lang/elixir/pull/13283) was an attempt to change it, but, as described there, it didn't bring improvement to examined projects.
48+
49+
Sometimes, though, async tests in a single module help a lot. One example is [Boombox](https://github.com/membraneframework/boombox), where there's a lot of IO-bound, independent tests, and no reason to move them to different modules. Another one is [Popcorn](https://github.com/software-mansion/popcorn), where tests are CPU-bound, but also independent and very unevenly distributed across modules.
50+
4651
## Authors
4752

4853
AsyncTest is created by Software Mansion.

lib/async_test.ex

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
defmodule AsyncTest do
22
@moduledoc """
3-
Makes tests within a single module run asynchronously.
3+
Makes tests within a single module (ExUnit Case) run asynchronously.
44
55
Just `import #{inspect(__MODULE__)}` and replace
66
`test` with `async_test`. It should be a drop-in
@@ -9,9 +9,8 @@ defmodule AsyncTest do
99
#{inspect(__MODULE__)} works in the following way:
1010
- create a public function instead of a test
1111
- create a new module with a single test that calls that function
12-
- copy all `@tags` to the newly created module
13-
- handle `setup` and `setup_all` similarly to `test`s - the `setup`
14-
in the new module calls a public function from the original module
12+
- mimic `@tags`, `setup`, `setup_all`, and `describe` structure
13+
in the new module
1514
- ensure `setup_all` is called only once - store its result in an
1615
`Agent` and retrieve it when needed
1716
"""

0 commit comments

Comments
 (0)