Skip to content

Fix mix test --only async:true/false #13639

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/ex_unit/lib/ex_unit/case.ex
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,7 @@ defmodule ExUnit.Case do

moduletag = Module.get_attribute(mod, :moduletag)
tag = Module.delete_attribute(mod, :tag)
{async, _parameterize} = Module.get_attribute(mod, :ex_unit_module)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of reading it here, maybe we can make it part of moduletag and that will just work? Then I think we can also remove it from __before_compile__ too.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another option is to set it inside ExUnit.Runner in run_module/prepare_tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We validate that the module tags don't set any reserved tags. Async is in the list of reserved tags. If we remove it there and do a Module.put_attribute(module, :moduletag, [async: async?]) in __register__ it would work, but then users can also do

defmodule MyTest do
  use ExUnit.Case

  @moduletag async: true
end

I don't know if that's fine. The current change is basically how it was previously and I'm really no expert on ExUnit internals :)


{name, describe, describe_line, describetag} =
case Module.get_attribute(mod, :ex_unit_describe) do
Expand All @@ -648,6 +649,7 @@ defmodule ExUnit.Case do
line: line,
file: file,
registered: registered,
async: async,
describe: describe,
describe_line: describe_line,
test_type: test_type
Expand Down
3 changes: 3 additions & 0 deletions lib/mix/test/fixtures/test_async/lib/a.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
defmodule A do
def f, do: :ok
end
3 changes: 3 additions & 0 deletions lib/mix/test/fixtures/test_async/lib/b.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
defmodule B do
def f, do: A.f()
end
11 changes: 11 additions & 0 deletions lib/mix/test/fixtures/test_async/mix.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
defmodule TestAsync.MixProject do
use Mix.Project

def project do
[
app: :test_async,
version: "0.0.1",
test_pattern: "*_test_async.exs"
]
end
end
7 changes: 7 additions & 0 deletions lib/mix/test/fixtures/test_async/test/a_test_async.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
defmodule ATest do
use ExUnit.Case, async: true

test "f async" do
assert A.f() == :ok
end
end
7 changes: 7 additions & 0 deletions lib/mix/test/fixtures/test_async/test/b_test_async.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
defmodule BTest do
use ExUnit.Case, async: false

test "f sync" do
assert B.f() == :ok
end
end
1 change: 1 addition & 0 deletions lib/mix/test/fixtures/test_async/test/test_helper.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ExUnit.start()
20 changes: 20 additions & 0 deletions lib/mix/test/mix/tasks/test_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,26 @@ defmodule Mix.Tasks.TestTest do
end
end

describe "--only" do
test "runs only async tests with --only async:true" do
in_fixture("test_async", fn ->
output = mix(["test", "--only", "async:true", "--trace"])
assert output =~ "2 tests, 0 failures, 1 excluded"
assert output =~ ~r/test f async \(.*ms\)/
assert output =~ "test f sync (excluded)"
end)
end

test "runs only sync tests with --only async:false" do
in_fixture("test_async", fn ->
output = mix(["test", "--only", "async:false", "--trace"])
assert output =~ "2 tests, 0 failures, 1 excluded"
assert output =~ ~r/test f sync \(.*ms\)/
assert output =~ "test f async (excluded)"
end)
end
end

defp receive_until_match(port, expected, acc) do
receive do
{^port, {:data, output}} ->
Expand Down