Skip to content

Commit 677e1ec

Browse files
authored
Add mix test --dry-run flag (#14499)
1 parent 67593e1 commit 677e1ec

File tree

6 files changed

+94
-7
lines changed

6 files changed

+94
-7
lines changed

lib/ex_unit/lib/ex_unit/cli_formatter.ex

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ defmodule ExUnit.CLIFormatter do
1818
IO.puts("")
1919

2020
config = %{
21+
dry_run: opts[:dry_run],
2122
trace: opts[:trace],
2223
colors: colors(opts),
2324
width: get_terminal_width(),
@@ -35,6 +36,8 @@ defmodule ExUnit.CLIFormatter do
3536
end
3637

3738
def handle_cast({:suite_started, _opts}, config) do
39+
if config.dry_run, do: IO.puts(extra_info("Tests that would be executed:", config))
40+
3841
{:noreply, config}
3942
end
4043

@@ -154,7 +157,15 @@ defmodule ExUnit.CLIFormatter do
154157
{:noreply, config}
155158
end
156159

157-
def handle_cast({:module_finished, %ExUnit.TestModule{state: nil}}, config) do
160+
def handle_cast({:module_finished, %ExUnit.TestModule{state: nil} = module}, config) do
161+
if config.dry_run do
162+
file_path = Path.relative_to_cwd(module.file)
163+
164+
Enum.each(module.tests, fn test ->
165+
IO.puts("#{file_path}:#{test.tags.line}")
166+
end)
167+
end
168+
158169
{:noreply, config}
159170
end
160171

@@ -453,6 +464,10 @@ defmodule ExUnit.CLIFormatter do
453464
colorize(:failure, msg, config)
454465
end
455466

467+
defp extra_info(msg, config) do
468+
colorize(:extra_info, msg, config)
469+
end
470+
456471
# Diff formatting
457472

458473
defp formatter(:diff_enabled?, _, %{colors: colors}),

lib/ex_unit/lib/ex_unit/runner.ex

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ defmodule ExUnit.Runner do
8888
seed: opts[:seed],
8989
stats_pid: stats_pid,
9090
timeout: opts[:timeout],
91-
trace: opts[:trace]
91+
trace: opts[:trace],
92+
dry_run: opts[:dry_run]
9293
}
9394
end
9495

@@ -306,6 +307,10 @@ defmodule ExUnit.Runner do
306307
{test_module, [], []}
307308
end
308309

310+
defp run_module_tests(%{dry_run: true}, test_module, _async?, tests) do
311+
{test_module, [], tests}
312+
end
313+
309314
defp run_module_tests(config, test_module, async?, tests) do
310315
Process.put(@current_key, test_module)
311316
%ExUnit.TestModule{name: module, tags: tags, parameters: params} = test_module

lib/ex_unit/mix.exs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ defmodule ExUnit.MixProject do
3939
timeout: 60000,
4040
trace: false,
4141
after_suite: [],
42-
repeat_until_failure: 0
42+
repeat_until_failure: 0,
43+
dry_run: false
4344
]
4445
]
4546
end

lib/mix/lib/mix/compilers/test.ex

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,12 @@ defmodule Mix.Compilers.Test do
3939
end
4040

4141
defp require_and_run(matched_test_files, test_paths, opts) do
42-
stale = opts[:stale]
42+
dry_run = Keyword.get(opts, :dry_run, false)
43+
stale = Keyword.get(opts, :stale, false)
4344
max_requires = opts[:max_requires]
4445

4546
{test_files, stale_manifest_pid, parallel_require_callbacks} =
46-
if stale do
47+
if stale and not dry_run do
4748
set_up_stale(matched_test_files, test_paths, opts)
4849
else
4950
{matched_test_files, nil, []}

lib/mix/lib/mix/tasks/test.ex

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ defmodule Mix.Tasks.Test do
121121
122122
* `--cover` - runs coverage tool. See "Coverage" section below
123123
124+
* `--dry-run` *(since v1.19.0)* - prints which tests would be run based on current options,
125+
but does not actually run any tests. This combines with all other options
126+
like `--stale`, `--only`, `--exclude`, and so on.
127+
124128
* `--exclude` - excludes tests that match the filter. This option may be given
125129
several times to apply different filters, such as `--exclude ci --exclude slow`
126130
@@ -494,7 +498,8 @@ defmodule Mix.Tasks.Test do
494498
warnings_as_errors: :boolean,
495499
profile_require: :string,
496500
exit_status: :integer,
497-
repeat_until_failure: :integer
501+
repeat_until_failure: :integer,
502+
dry_run: :boolean
498503
]
499504

500505
@cover [output: "cover", tool: Mix.Tasks.Test.Coverage]
@@ -847,7 +852,8 @@ defmodule Mix.Tasks.Test do
847852
:only_test_ids,
848853
:test_location_relative_path,
849854
:exit_status,
850-
:repeat_until_failure
855+
:repeat_until_failure,
856+
:dry_run
851857
]
852858

853859
@doc false

lib/mix/test/mix/tasks/test_test.exs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,65 @@ defmodule Mix.Tasks.TestTest do
716716
end
717717
end
718718

719+
describe "--dry-run" do
720+
test "works with --stale" do
721+
in_fixture("test_stale", fn ->
722+
File.write!("test/dry_run_one_test_stale.exs", """
723+
defmodule DryRunOneTest do
724+
use ExUnit.Case
725+
726+
test "new test" do
727+
assert true
728+
end
729+
end
730+
""")
731+
732+
File.write!("test/dry_run_two_test_stale.exs", """
733+
defmodule DryRunTwoTest do
734+
use ExUnit.Case
735+
736+
@tag :skip
737+
test "skipped test" do
738+
assert true
739+
end
740+
end
741+
""")
742+
743+
output = mix(["test", "--dry-run", "--stale"])
744+
assert output =~ "Tests that would be executed:"
745+
assert output =~ "test/a_test_stale.exs:4"
746+
assert output =~ "test/b_test_stale.exs:4"
747+
assert output =~ "test/dry_run_one_test_stale.exs:4"
748+
refute output =~ "test/dry_run_two_test_stale.exs:5"
749+
assert output =~ "1 test, 0 failures, 1 skipped"
750+
751+
# Tests should still be marked as stale
752+
output = mix(["test", "--dry-run", "--stale"])
753+
assert output =~ "1 test, 0 failures, 1 skipped"
754+
end)
755+
end
756+
757+
test "works with --failed" do
758+
in_fixture("test_failed", fn ->
759+
output = mix(["test"])
760+
assert output =~ "4 tests, 2 failures"
761+
762+
output = mix(["test", "--dry-run", "--failed"])
763+
assert output =~ "Tests that would be executed:"
764+
assert output =~ "test/only_failing_test_failed.exs:4"
765+
assert output =~ "test/passing_and_failing_test_failed.exs:5"
766+
assert output =~ "0 tests, 0 failures"
767+
768+
# Force the tests to pass, verify dry-run doesn't actually run them
769+
System.put_env("PASS_FAILING_TESTS", "true")
770+
output = mix(["test", "--dry-run", "--failed"])
771+
assert output =~ "0 tests, 0 failures"
772+
end)
773+
after
774+
System.delete_env("PASS_FAILING_TESTS")
775+
end
776+
end
777+
719778
defp receive_until_match(port, expected, acc) do
720779
receive do
721780
{^port, {:data, output}} ->

0 commit comments

Comments
 (0)