From 2310bed81694f1d031ce99c2ccf159c4bf2b2d9b Mon Sep 17 00:00:00 2001 From: Andrea Leopardi Date: Tue, 10 Mar 2026 08:42:14 +0100 Subject: [PATCH 1/3] Improve ExUnit failure/success output --- lib/ex_unit/lib/ex_unit/cli_formatter.ex | 77 +++++++++++++++++---- lib/ex_unit/test/ex_unit/callbacks_test.exs | 12 ++-- lib/ex_unit/test/ex_unit/doc_test_test.exs | 16 ++--- lib/ex_unit/test/ex_unit/register_test.exs | 4 +- lib/ex_unit/test/ex_unit_test.exs | 63 ++++++++--------- 5 files changed, 111 insertions(+), 61 deletions(-) diff --git a/lib/ex_unit/lib/ex_unit/cli_formatter.ex b/lib/ex_unit/lib/ex_unit/cli_formatter.ex index 98f73f8f1a5..8a16d2b0d61 100644 --- a/lib/ex_unit/lib/ex_unit/cli_formatter.ex +++ b/lib/ex_unit/lib/ex_unit/cli_formatter.ex @@ -27,6 +27,7 @@ defmodule ExUnit.CLIFormatter do test_counter: %{}, test_timings: [], failure_counter: 0, + failure_type_counter: %{}, skipped_counter: 0, excluded_counter: 0, invalid_counter: 0 @@ -139,7 +140,14 @@ defmodule ExUnit.CLIFormatter do test_counter = update_test_counter(config.test_counter, test) failure_counter = config.failure_counter + 1 - config = %{config | test_counter: test_counter, failure_counter: failure_counter} + failure_type_counter = update_test_counter(config.failure_type_counter, test) + + config = %{ + config + | test_counter: test_counter, + failure_counter: failure_counter, + failure_type_counter: failure_type_counter + } {:noreply, update_test_timings(config, test)} end @@ -176,8 +184,16 @@ defmodule ExUnit.CLIFormatter do # The failed tests have already contributed to the counter, # so we should only add the successful tests to the count config = - update_in(config.failure_counter, fn counter -> - counter + Enum.count(test_module.tests, &is_nil(&1.state)) + Enum.reduce(test_module.tests, config, fn + %{state: nil} = test, acc -> + %{ + acc + | failure_counter: acc.failure_counter + 1, + failure_type_counter: update_test_counter(acc.failure_type_counter, test) + } + + _test, acc -> + acc end) formatted = @@ -352,11 +368,28 @@ defmodule ExUnit.CLIFormatter do defp print_summary(config, force_failures?) do test_type_counts = collect_test_type_counts(config) test_counter = test_counter_or_default(config, test_type_counts) - formatted_test_type_counts = format_test_type_counts(test_counter) - failure_pl = pluralize(config.failure_counter, "failure", "failures") + + passed_total = + test_type_counts - config.failure_counter - config.skipped_counter - config.invalid_counter + + # Passed line: "Passed: 447/455 (53/54 doctests, 393/403 tests)" + passed_breakdown = format_passed_breakdown(test_counter, config.failure_type_counter) + + passed_line = + "Passed: #{passed_total}/#{test_type_counts}" + |> if_true(passed_breakdown != "", &(&1 <> " (#{passed_breakdown})")) + + # Failed line: "Failed: 8 tests, 1 property" + failed_line = + if config.failure_counter > 0 do + failed_breakdown = format_type_counts(config.failure_type_counter) + "\n" <> failure("Failed: #{failed_breakdown}", config) + else + "" + end message = - "#{formatted_test_type_counts}#{config.failure_counter} #{failure_pl}" + passed_line |> if_true( config.invalid_counter > 0, &(&1 <> ", #{config.invalid_counter} invalid") @@ -372,7 +405,7 @@ defmodule ExUnit.CLIFormatter do cond do config.failure_counter > 0 or force_failures? -> - IO.puts(failure(message, config)) + IO.puts(message <> failed_line) config.invalid_counter > 0 -> IO.puts(invalid(message, config)) @@ -404,14 +437,34 @@ defmodule ExUnit.CLIFormatter do IO.puts(formatted) end - defp format_test_type_counts(test_counter) do - test_counter + defp format_type_counts(type_counter) do + type_counter |> Enum.sort() |> Enum.map(fn {test_type, count} -> - type_pluralized = pluralize(count, test_type, ExUnit.plural_rule(test_type |> to_string())) - - "#{count} #{type_pluralized}, " + "#{count} #{pluralize_type(count, test_type)}" end) + |> Enum.join(", ") + end + + defp format_passed_breakdown(test_counter, failure_type_counter) do + types = test_counter |> Map.keys() |> Enum.sort() + + if length(types) <= 1 do + "" + else + types + |> Enum.map(fn type -> + total = Map.get(test_counter, type, 0) + failed = Map.get(failure_type_counter, type, 0) + passed = total - failed + "#{passed}/#{total} #{pluralize_type(total, type)}" + end) + |> Enum.join(", ") + end + end + + defp pluralize_type(count, type) do + pluralize(count, type, ExUnit.plural_rule(to_string(type))) end defp test_counter_or_default(_config, 0) do diff --git a/lib/ex_unit/test/ex_unit/callbacks_test.exs b/lib/ex_unit/test/ex_unit/callbacks_test.exs index 81ea80b2b91..8004ef0f825 100644 --- a/lib/ex_unit/test/ex_unit/callbacks_test.exs +++ b/lib/ex_unit/test/ex_unit/callbacks_test.exs @@ -36,7 +36,7 @@ defmodule ExUnit.CallbacksTest do end end - assert capture_io(fn -> ExUnit.run() end) =~ "1 test, 0 failures" + assert capture_io(fn -> ExUnit.run() end) =~ "Passed: 1/1" end test "named callbacks run custom code in order" do @@ -66,7 +66,7 @@ defmodule ExUnit.CallbacksTest do defp store_5(context), do: store(context, 5) end - assert capture_io(fn -> ExUnit.run() end) =~ "1 test, 0 failures" + assert capture_io(fn -> ExUnit.run() end) =~ "Passed: 1/1" end test "named callbacks support {module, function} tuples" do @@ -87,7 +87,7 @@ defmodule ExUnit.CallbacksTest do def setup_3(_), do: [setup_3: true] end - assert capture_io(fn -> ExUnit.run() end) =~ "1 test, 0 failures" + assert capture_io(fn -> ExUnit.run() end) =~ "Passed: 1/1" end test "doesn't choke on setup errors" do @@ -141,7 +141,7 @@ defmodule ExUnit.CallbacksTest do end end - assert capture_io(fn -> ExUnit.run() end) =~ "1 test, 0 failures, 1 invalid" + assert capture_io(fn -> ExUnit.run() end) =~ "Passed: 0/1" end test "doesn't choke on dead supervisor" do @@ -209,7 +209,7 @@ defmodule ExUnit.CallbacksTest do end end - assert capture_io(fn -> ExUnit.run() end) =~ "2 tests, 2 failures" + assert capture_io(fn -> ExUnit.run() end) =~ "Failed: 2 tests" end defp no_formatters! do @@ -253,7 +253,7 @@ defmodule ExUnit.CallbacksTest do output = capture_io(fn -> ExUnit.run() end) assert output =~ "on_exit run" - assert output =~ "1 test, 0 failures" + assert output =~ "Passed: 1/1" end test "runs multiple on_exit exits and overrides by ref" do diff --git a/lib/ex_unit/test/ex_unit/doc_test_test.exs b/lib/ex_unit/test/ex_unit/doc_test_test.exs index fffb4cbe5b0..6ce25188e33 100644 --- a/lib/ex_unit/test/ex_unit/doc_test_test.exs +++ b/lib/ex_unit/test/ex_unit/doc_test_test.exs @@ -616,7 +616,7 @@ defmodule ExUnit.DocTestTest do doctest ExUnit.DocTestTest.SomewhatGoodModuleWithOnly, only: [one: 0, two: 0], import: true end - assert capture_io(fn -> ExUnit.run() end) =~ "2 doctests, 1 failure" + assert capture_io(fn -> ExUnit.run() end) =~ "Failed: 1 doctest" end test "empty :only" do @@ -627,7 +627,7 @@ defmodule ExUnit.DocTestTest do output = capture_io(fn -> ExUnit.run() end) - assert output =~ "0 failures" + refute output =~ "Failed:" refute output =~ "doctest" end @@ -639,7 +639,7 @@ defmodule ExUnit.DocTestTest do output = capture_io(fn -> ExUnit.run() end) - assert output =~ "0 failures" + refute output =~ "Failed:" assert output =~ "2 skipped" end @@ -763,7 +763,7 @@ defmodule ExUnit.DocTestTest do assert output =~ "#{stack(starting_line + 28)}ExUnit.DocTestTest.Failure (module)" - assert output =~ "8 doctests, 8 failures" + assert output =~ "Failed: 8 doctests" end test "doctest invalid" do @@ -969,7 +969,7 @@ defmodule ExUnit.DocTestTest do #{stack(line)}ExUnit.DocTestTest.Invalid (module) """ - assert output =~ "10 doctests, 10 failures" + assert output =~ "Failed: 10 doctests" end test "pattern matching assertions in doctests" do @@ -1075,7 +1075,7 @@ defmodule ExUnit.DocTestTest do (for doctest at) #{location}:#{starting_line + 19}: (test) """ - assert output =~ "10 doctests, 8 failures" + assert output =~ "Failed: 8 doctests" end test "IEx prefix contains a number" do @@ -1084,7 +1084,7 @@ defmodule ExUnit.DocTestTest do doctest ExUnit.DocTestTest.Numbered end - assert capture_io(fn -> ExUnit.run() end) =~ "1 doctest, 0 failures" + assert capture_io(fn -> ExUnit.run() end) =~ "Passed: 1/1" end test "IEx prompt contains host" do @@ -1253,7 +1253,7 @@ defmodule ExUnit.DocTestTest do end output = capture_io(fn -> ExUnit.run() end) - assert output =~ "2 doctests, 0 failures" + assert output =~ "Passed: 2/2" end test "failing" do diff --git a/lib/ex_unit/test/ex_unit/register_test.exs b/lib/ex_unit/test/ex_unit/register_test.exs index 8dd2f730f57..640ae092355 100644 --- a/lib/ex_unit/test/ex_unit/register_test.exs +++ b/lib/ex_unit/test/ex_unit/register_test.exs @@ -42,7 +42,7 @@ defmodule ExUnit.RegisterTest do assert capture_io(fn -> assert ExUnit.run() == %{failures: 0, skipped: 0, total: 2, excluded: 0} - end) =~ "1 property, 1 test, 0 failures" + end) =~ "Passed: 2/2 (1/1 property, 1/1 test)" end test "plural test types" do @@ -96,6 +96,6 @@ defmodule ExUnit.RegisterTest do assert capture_io(fn -> assert ExUnit.run() == %{failures: 0, skipped: 0, total: 4, excluded: 0} - end) =~ "2 properties, 2 tests, 0 failures" + end) =~ "Passed: 4/4 (2/2 properties, 2/2 tests)" end end diff --git a/lib/ex_unit/test/ex_unit_test.exs b/lib/ex_unit/test/ex_unit_test.exs index 6fded1e4533..c69029774d5 100644 --- a/lib/ex_unit/test/ex_unit_test.exs +++ b/lib/ex_unit/test/ex_unit_test.exs @@ -26,14 +26,14 @@ defmodule ExUnitTest do assert capture_io(fn -> assert ExUnit.run() == %{failures: 2, skipped: 0, total: 2, excluded: 0} - end) =~ "\n2 tests, 2 failures\n" + end) =~ "Failed: 2 tests" ExUnit.Server.modules_loaded(false) assert capture_io(fn -> assert ExUnit.async_run() |> ExUnit.await_run() == %{failures: 0, skipped: 0, total: 0, excluded: 0} - end) =~ "\n0 tests, 0 failures\n" + end) =~ "\nPassed: 0/0\n" end test "supports rerunning given modules" do @@ -70,7 +70,7 @@ defmodule ExUnitTest do total: 1, excluded: 0 } - end) =~ "\n1 test, 1 failure\n" + end) =~ "Failed: 1 test" sample = [SampleSyncTest, SampleAsyncTest] @@ -81,7 +81,7 @@ defmodule ExUnitTest do total: 2, excluded: 0 } - end) =~ "\n2 tests, 2 failures\n" + end) =~ "Failed: 2 tests" assert capture_io(fn -> assert ExUnit.run(sample ++ sample) == %{ @@ -90,7 +90,7 @@ defmodule ExUnitTest do total: 2, excluded: 0 } - end) =~ "\n2 tests, 2 failures\n" + end) =~ "Failed: 2 tests" end test "prints aborted runs on sigquit", config do @@ -138,11 +138,8 @@ defmodule ExUnitTest do assert result =~ ~r"\* ExUnitTest.SleepOnSetupAll \[.*test/ex_unit_test.exs\]" assert result =~ ~r"\* test true \[.*test/ex_unit_test.exs:#{line}\]" - assert result =~ """ - Showing results so far... - - 0 tests, 0 failures - """ + assert result =~ "Showing results so far..." + assert result =~ "Passed: 0/0" end test "doesn't hang on exits" do @@ -162,7 +159,7 @@ defmodule ExUnitTest do assert capture_io(fn -> assert ExUnit.run() == %{failures: 1, skipped: 0, total: 1, excluded: 0} - end) =~ "\n1 test, 1 failure\n" + end) =~ "Failed: 1 test" end test "reports capture log crashes" do @@ -180,7 +177,7 @@ defmodule ExUnitTest do assert capture_io(fn -> assert ExUnit.run() == %{failures: 1, skipped: 0, total: 1, excluded: 0} - end) =~ "\n1 test, 1 failure\n" + end) =~ "Failed: 1 test" end test "supports timeouts" do @@ -309,7 +306,7 @@ defmodule ExUnitTest do {result, output} = run_with_filter([only_test_ids: test_ids], []) assert result == %{failures: 1, skipped: 0, excluded: 0, total: 1} - assert output =~ "\n1 test, 1 failure\n" + assert output =~ "Failed: 1 test" end test "filtering cases with tags" do @@ -331,23 +328,23 @@ defmodule ExUnitTest do # Empty because it is already loaded {result, output} = run_with_filter([], []) assert result == %{failures: 1, skipped: 0, total: 4, excluded: 0} - assert output =~ "\n4 tests, 1 failure\n" + assert output =~ "Failed: 1 test" {result, output} = run_with_filter([exclude: [even: true]], [ParityTest]) assert result == %{failures: 0, skipped: 0, excluded: 1, total: 4} - assert output =~ "\n3 tests, 0 failures (1 excluded)\n" + assert output =~ "Passed: 3/3" {result, output} = run_with_filter([exclude: :even], [ParityTest]) assert result == %{failures: 0, skipped: 0, excluded: 3, total: 4} - assert output =~ "\n1 test, 0 failures (3 excluded)\n" + assert output =~ "Passed: 1/1" {result, output} = run_with_filter([exclude: :even, include: [even: true]], [ParityTest]) assert result == %{failures: 1, skipped: 0, excluded: 2, total: 4} - assert output =~ "\n2 tests, 1 failure (2 excluded)\n" + assert output =~ "Failed: 1 test" {result, output} = run_with_filter([exclude: :test, include: [even: true]], [ParityTest]) assert result == %{failures: 1, skipped: 0, excluded: 3, total: 4} - assert output =~ "\n1 test, 1 failure (3 excluded)\n" + assert output =~ "Failed: 1 test" end test "log capturing" do @@ -414,7 +411,7 @@ defmodule ExUnitTest do assert ExUnit.run() == %{failures: 1, skipped: 0, total: 1, excluded: 0} end) - assert output =~ "\n1 test, 1 failure\n" + assert output =~ "Failed: 1 test" assert output =~ "\n 1) test multi (ExUnitTest.MultiTest)\n" assert output =~ "Failure #1\n" assert output =~ "Failure #2\n" @@ -470,7 +467,7 @@ defmodule ExUnitTest do end) assert output =~ "Not implemented\n" - assert output =~ "\n1 test, 1 failure\n" + assert output =~ "Failed: 1 test" end test "skips tagged test with skip" do @@ -496,7 +493,7 @@ defmodule ExUnitTest do assert ExUnit.run() == %{failures: 0, skipped: 2, total: 2, excluded: 0} end) - assert output =~ "\n2 tests, 0 failures, 2 skipped\n" + assert output =~ "Passed: 0/2" end test "filtering cases with :module tag" do @@ -514,7 +511,7 @@ defmodule ExUnitTest do {result, output} = run_with_filter([exclude: :module], []) assert result == %{failures: 0, skipped: 0, excluded: 2, total: 2} - assert output =~ "\n0 tests, 0 failures (2 excluded)\n" + assert output =~ "Passed: 0/0" {result, output} = [exclude: :test, include: [module: "ExUnitTest.SecondTestModule"]] @@ -522,7 +519,7 @@ defmodule ExUnitTest do assert result == %{failures: 1, skipped: 0, excluded: 1, total: 2} assert output =~ "\n 1) test false (ExUnitTest.SecondTestModule)\n" - assert output =~ "\n1 test, 1 failure (1 excluded)\n" + assert output =~ "Failed: 1 test" end test "raises on reserved tag :file in module" do @@ -647,7 +644,7 @@ defmodule ExUnitTest do assert capture_io(fn -> assert ExUnit.run() == %{failures: 0, skipped: 0, total: 3, excluded: 0} - end) =~ "\n3 tests, 0 failures\n" + end) =~ "Passed: 3/3" end # Skipped and excluded tests should be included in the stats @@ -685,7 +682,7 @@ defmodule ExUnitTest do end) refute output =~ max_failures_reached_msg() - assert output =~ "\n5 tests, 0 failures, 4 invalid, 1 skipped (1 excluded)\n" + assert output =~ "Passed: 0/5" end test "parameterized tests" do @@ -730,7 +727,7 @@ defmodule ExUnitTest do end configure_and_reload_on_exit(trace: true) - assert capture_io(fn -> ExUnit.run() end) =~ "0 tests" + assert capture_io(fn -> ExUnit.run() end) =~ "Passed: 0/0" defmodule EmptyGroupedParameterizedTests do use ExUnit.Case, async: true, parameterize: [], group: :example @@ -741,7 +738,7 @@ defmodule ExUnitTest do end configure_and_reload_on_exit(trace: true) - assert capture_io(fn -> ExUnit.run() end) =~ "0 tests" + assert capture_io(fn -> ExUnit.run() end) =~ "Passed: 0/0" end describe "after_suite/1" do @@ -816,7 +813,7 @@ defmodule ExUnitTest do end) assert output =~ max_failures_reached_msg() - assert output =~ "\n5 tests, 2 failures, 1 skipped (1 excluded)\n" + assert output =~ "Failed: 2 tests" end test ":max_failures is not reached" do @@ -847,7 +844,7 @@ defmodule ExUnitTest do end) refute output =~ max_failures_reached_msg() - assert output =~ "\n6 tests, 2 failures, 1 skipped (2 excluded)\n" + assert output =~ "Failed: 2 tests" end test ":max_failures has been reached" do @@ -881,7 +878,7 @@ defmodule ExUnitTest do end) assert output =~ max_failures_reached_msg() - assert output =~ "\n5 tests, 2 failures, 2 skipped (2 excluded)\n" + assert output =~ "Failed: 2 tests" end # Excluded and skipped tests are detected before setup_all @@ -915,7 +912,7 @@ defmodule ExUnitTest do end) assert output =~ max_failures_reached_msg() - assert output =~ "\n3 tests, 0 failures, 2 invalid, 1 skipped (1 excluded)\n" + assert output =~ "Passed: 0/3" end test ":max_failures flushes all async/sync cases" do @@ -942,7 +939,7 @@ defmodule ExUnitTest do end) assert output =~ max_failures_reached_msg() - assert output =~ "\n1 test, 1 failure\n" + assert output =~ "Failed: 1 test" capture_io(fn -> assert ExUnit.run() == %{total: 0, failures: 0, excluded: 0, skipped: 0} @@ -1106,7 +1103,7 @@ defmodule ExUnitTest do end) assert output =~ "All tests have been excluded.\n" - assert output =~ "0 tests, 0 failures (2 excluded)\n" + assert output =~ "Passed: 0/0" end test "tests are run in compile order (FIFO)" do From 53dffc9a31fd16f70150b2052d235f12cffc62aa Mon Sep 17 00:00:00 2001 From: Andrea Leopardi Date: Tue, 10 Mar 2026 09:24:28 +0100 Subject: [PATCH 2/3] FIXUP --- lib/ex_unit/lib/ex_unit/cli_formatter.ex | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/ex_unit/lib/ex_unit/cli_formatter.ex b/lib/ex_unit/lib/ex_unit/cli_formatter.ex index 8a16d2b0d61..28f072e99ca 100644 --- a/lib/ex_unit/lib/ex_unit/cli_formatter.ex +++ b/lib/ex_unit/lib/ex_unit/cli_formatter.ex @@ -447,19 +447,20 @@ defmodule ExUnit.CLIFormatter do end defp format_passed_breakdown(test_counter, failure_type_counter) do - types = test_counter |> Map.keys() |> Enum.sort() - - if length(types) <= 1 do + # If there are no different test types, we just print "Passed: N/N" + # without the type. + if map_size(test_counter) in 0..1 do "" else - types - |> Enum.map(fn type -> - total = Map.get(test_counter, type, 0) + test_counter + |> Map.keys() + |> Enum.sort() + |> Enum.map_join(", ", fn type -> + total = Map.fetch!(test_counter, type) failed = Map.get(failure_type_counter, type, 0) passed = total - failed "#{passed}/#{total} #{pluralize_type(total, type)}" end) - |> Enum.join(", ") end end From 5348f7f408ebdb3964c2b0e4443b9f24eaabe990 Mon Sep 17 00:00:00 2001 From: Andrea Leopardi Date: Tue, 10 Mar 2026 11:20:10 +0100 Subject: [PATCH 3/3] FIXUP --- lib/ex_unit/lib/ex_unit/cli_formatter.ex | 29 +++++++++++++++------ lib/ex_unit/test/ex_unit/callbacks_test.exs | 8 +++--- lib/ex_unit/test/ex_unit/doc_test_test.exs | 4 +-- lib/ex_unit/test/ex_unit/register_test.exs | 4 +-- lib/ex_unit/test/ex_unit_test.exs | 18 ++++++------- 5 files changed, 38 insertions(+), 25 deletions(-) diff --git a/lib/ex_unit/lib/ex_unit/cli_formatter.ex b/lib/ex_unit/lib/ex_unit/cli_formatter.ex index 28f072e99ca..dd3247db16b 100644 --- a/lib/ex_unit/lib/ex_unit/cli_formatter.ex +++ b/lib/ex_unit/lib/ex_unit/cli_formatter.ex @@ -372,11 +372,19 @@ defmodule ExUnit.CLIFormatter do passed_total = test_type_counts - config.failure_counter - config.skipped_counter - config.invalid_counter - # Passed line: "Passed: 447/455 (53/54 doctests, 393/403 tests)" - passed_breakdown = format_passed_breakdown(test_counter, config.failure_type_counter) + # Passed line: "Passed: 447/455 (53/54 doctests, 393/403 tests)" or + # "Passed: 455 (70 tests, 14 properties)" when all pass + all_passed? = passed_total == test_type_counts + + passed_breakdown = + format_passed_breakdown(test_counter, config.failure_type_counter, all_passed?) passed_line = - "Passed: #{passed_total}/#{test_type_counts}" + if all_passed? do + "Passed: #{passed_total}" + else + "Passed: #{passed_total}/#{test_type_counts}" + end |> if_true(passed_breakdown != "", &(&1 <> " (#{passed_breakdown})")) # Failed line: "Failed: 8 tests, 1 property" @@ -389,7 +397,7 @@ defmodule ExUnit.CLIFormatter do end message = - passed_line + ("\n" <> passed_line) |> if_true( config.invalid_counter > 0, &(&1 <> ", #{config.invalid_counter} invalid") @@ -446,7 +454,7 @@ defmodule ExUnit.CLIFormatter do |> Enum.join(", ") end - defp format_passed_breakdown(test_counter, failure_type_counter) do + defp format_passed_breakdown(test_counter, failure_type_counter, all_passed?) do # If there are no different test types, we just print "Passed: N/N" # without the type. if map_size(test_counter) in 0..1 do @@ -457,9 +465,14 @@ defmodule ExUnit.CLIFormatter do |> Enum.sort() |> Enum.map_join(", ", fn type -> total = Map.fetch!(test_counter, type) - failed = Map.get(failure_type_counter, type, 0) - passed = total - failed - "#{passed}/#{total} #{pluralize_type(total, type)}" + + if all_passed? do + "#{total} #{pluralize_type(total, type)}" + else + failed = Map.get(failure_type_counter, type, 0) + passed = total - failed + "#{passed}/#{total} #{pluralize_type(total, type)}" + end end) end end diff --git a/lib/ex_unit/test/ex_unit/callbacks_test.exs b/lib/ex_unit/test/ex_unit/callbacks_test.exs index 8004ef0f825..e94fdc1c0f4 100644 --- a/lib/ex_unit/test/ex_unit/callbacks_test.exs +++ b/lib/ex_unit/test/ex_unit/callbacks_test.exs @@ -36,7 +36,7 @@ defmodule ExUnit.CallbacksTest do end end - assert capture_io(fn -> ExUnit.run() end) =~ "Passed: 1/1" + assert capture_io(fn -> ExUnit.run() end) =~ "Passed: 1" end test "named callbacks run custom code in order" do @@ -66,7 +66,7 @@ defmodule ExUnit.CallbacksTest do defp store_5(context), do: store(context, 5) end - assert capture_io(fn -> ExUnit.run() end) =~ "Passed: 1/1" + assert capture_io(fn -> ExUnit.run() end) =~ "Passed: 1" end test "named callbacks support {module, function} tuples" do @@ -87,7 +87,7 @@ defmodule ExUnit.CallbacksTest do def setup_3(_), do: [setup_3: true] end - assert capture_io(fn -> ExUnit.run() end) =~ "Passed: 1/1" + assert capture_io(fn -> ExUnit.run() end) =~ "Passed: 1" end test "doesn't choke on setup errors" do @@ -253,7 +253,7 @@ defmodule ExUnit.CallbacksTest do output = capture_io(fn -> ExUnit.run() end) assert output =~ "on_exit run" - assert output =~ "Passed: 1/1" + assert output =~ "Passed: 1" end test "runs multiple on_exit exits and overrides by ref" do diff --git a/lib/ex_unit/test/ex_unit/doc_test_test.exs b/lib/ex_unit/test/ex_unit/doc_test_test.exs index 6ce25188e33..80729467b4c 100644 --- a/lib/ex_unit/test/ex_unit/doc_test_test.exs +++ b/lib/ex_unit/test/ex_unit/doc_test_test.exs @@ -1084,7 +1084,7 @@ defmodule ExUnit.DocTestTest do doctest ExUnit.DocTestTest.Numbered end - assert capture_io(fn -> ExUnit.run() end) =~ "Passed: 1/1" + assert capture_io(fn -> ExUnit.run() end) =~ "Passed: 1" end test "IEx prompt contains host" do @@ -1253,7 +1253,7 @@ defmodule ExUnit.DocTestTest do end output = capture_io(fn -> ExUnit.run() end) - assert output =~ "Passed: 2/2" + assert output =~ "Passed: 2" end test "failing" do diff --git a/lib/ex_unit/test/ex_unit/register_test.exs b/lib/ex_unit/test/ex_unit/register_test.exs index 640ae092355..2ea59b0502b 100644 --- a/lib/ex_unit/test/ex_unit/register_test.exs +++ b/lib/ex_unit/test/ex_unit/register_test.exs @@ -42,7 +42,7 @@ defmodule ExUnit.RegisterTest do assert capture_io(fn -> assert ExUnit.run() == %{failures: 0, skipped: 0, total: 2, excluded: 0} - end) =~ "Passed: 2/2 (1/1 property, 1/1 test)" + end) =~ "Passed: 2 (1 property, 1 test)" end test "plural test types" do @@ -96,6 +96,6 @@ defmodule ExUnit.RegisterTest do assert capture_io(fn -> assert ExUnit.run() == %{failures: 0, skipped: 0, total: 4, excluded: 0} - end) =~ "Passed: 4/4 (2/2 properties, 2/2 tests)" + end) =~ "Passed: 4 (2 properties, 2 tests)" end end diff --git a/lib/ex_unit/test/ex_unit_test.exs b/lib/ex_unit/test/ex_unit_test.exs index c69029774d5..b42c39b5747 100644 --- a/lib/ex_unit/test/ex_unit_test.exs +++ b/lib/ex_unit/test/ex_unit_test.exs @@ -33,7 +33,7 @@ defmodule ExUnitTest do assert capture_io(fn -> assert ExUnit.async_run() |> ExUnit.await_run() == %{failures: 0, skipped: 0, total: 0, excluded: 0} - end) =~ "\nPassed: 0/0\n" + end) =~ "\nPassed: 0\n" end test "supports rerunning given modules" do @@ -139,7 +139,7 @@ defmodule ExUnitTest do assert result =~ ~r"\* test true \[.*test/ex_unit_test.exs:#{line}\]" assert result =~ "Showing results so far..." - assert result =~ "Passed: 0/0" + assert result =~ "Passed: 0" end test "doesn't hang on exits" do @@ -332,11 +332,11 @@ defmodule ExUnitTest do {result, output} = run_with_filter([exclude: [even: true]], [ParityTest]) assert result == %{failures: 0, skipped: 0, excluded: 1, total: 4} - assert output =~ "Passed: 3/3" + assert output =~ "Passed: 3" {result, output} = run_with_filter([exclude: :even], [ParityTest]) assert result == %{failures: 0, skipped: 0, excluded: 3, total: 4} - assert output =~ "Passed: 1/1" + assert output =~ "Passed: 1" {result, output} = run_with_filter([exclude: :even, include: [even: true]], [ParityTest]) assert result == %{failures: 1, skipped: 0, excluded: 2, total: 4} @@ -511,7 +511,7 @@ defmodule ExUnitTest do {result, output} = run_with_filter([exclude: :module], []) assert result == %{failures: 0, skipped: 0, excluded: 2, total: 2} - assert output =~ "Passed: 0/0" + assert output =~ "Passed: 0" {result, output} = [exclude: :test, include: [module: "ExUnitTest.SecondTestModule"]] @@ -644,7 +644,7 @@ defmodule ExUnitTest do assert capture_io(fn -> assert ExUnit.run() == %{failures: 0, skipped: 0, total: 3, excluded: 0} - end) =~ "Passed: 3/3" + end) =~ "Passed: 3" end # Skipped and excluded tests should be included in the stats @@ -727,7 +727,7 @@ defmodule ExUnitTest do end configure_and_reload_on_exit(trace: true) - assert capture_io(fn -> ExUnit.run() end) =~ "Passed: 0/0" + assert capture_io(fn -> ExUnit.run() end) =~ "Passed: 0" defmodule EmptyGroupedParameterizedTests do use ExUnit.Case, async: true, parameterize: [], group: :example @@ -738,7 +738,7 @@ defmodule ExUnitTest do end configure_and_reload_on_exit(trace: true) - assert capture_io(fn -> ExUnit.run() end) =~ "Passed: 0/0" + assert capture_io(fn -> ExUnit.run() end) =~ "Passed: 0" end describe "after_suite/1" do @@ -1103,7 +1103,7 @@ defmodule ExUnitTest do end) assert output =~ "All tests have been excluded.\n" - assert output =~ "Passed: 0/0" + assert output =~ "Passed: 0" end test "tests are run in compile order (FIFO)" do