View Source ExUnit.Formatter (ExUnit v1.17.3)
Helper functions for formatting and the formatting protocols.
Formatters are GenServer
s specified during ExUnit configuration
that receive a series of events as casts.
The following events are possible:
{:suite_started, opts}
- the suite has started with the specified options to the runner.{:suite_finished, times_us}
- the suite has finished. Returns several measurements in microseconds for running the suite. Seet:times_us
for more information.{:module_started, test_module}
- a test module has started. SeeExUnit.TestModule
for details.{:module_finished, test_module}
- a test module has finished. SeeExUnit.TestModule
for details.{:test_started, test}
- a test has started. SeeExUnit.Test
for details.{:test_finished, test}
- a test has finished. SeeExUnit.Test
for details.{:sigquit, [test | test_module]}
- the VM is going to shutdown. It receives the test cases (or test module in case ofsetup_all
) still running.:max_failures_reached
- the test run has been aborted due to reaching max failures limit set with:max_failures
option
The formatter will also receive the following events but they are deprecated and should be ignored:
{:case_started, test_module}
- a test module has started. SeeExUnit.TestModule
for details.{:case_finished, test_module}
- a test module has finished. SeeExUnit.TestModule
for details.
The full ExUnit configuration is passed as the argument to GenServer.init/1
callback when the formatters are started. If you need to do runtime configuration
of a formatter, you can add any configuration needed by using ExUnit.configure/1
or ExUnit.start/1
, and this will then be included in the options passed to
the GenServer.init/1
callback.
Summary
Types
A function that this module calls to format various things.
Key passed to a formatter callback to format a diff.
Key passed to a formatter callback to format information.
The times spent on several parts of the test suite.
Width for formatting.
Functions
Formats ExUnit.AssertionError
diff.
Formats filters used to constrain cases to be run.
Receives a test module and formats its failure.
Receives a test and formats its failures.
Formats time taken running the test suite.
Types
@type formatter_callback() :: (:diff_enabled?, boolean() -> boolean()) | (formatter_callback_diff_key(), Inspect.Algebra.t() -> Inspect.Algebra.t()) | (formatter_callback_info_key(), String.t() -> String.t())
A function that this module calls to format various things.
You can pass this functions to various functions in this module, and use it to customize the formatting of the output. For example, ExUnit's CLI formatter uses this callback to colorize output.
Keys
The possible keys are:
:diff_enabled?
- whether diffing is enabled. It receives a boolean indicating whether diffing is enabled by default and returns a boolean indicating whether diffing should be enabled for the current test.:diff_delete
and:diff_delete_whitespace
- Should format a diff deletion, with or without whitespace respectively.:diff_insert
and:diff_insert_whitespace
- Should format a diff insertion, with or without whitespace respectively.:extra_info
- Should format extra information, such as the"code: "
label that precedes code to show.:error_info
- Should format error information.:test_module_info
- Should format test module information. The message returned when this key is passed precedes messages such as"failure on setup_all callback [...]"
.:test_info
- Should format test information.:location_info
- Should format test location information.:stacktrace_info
- Should format stacktrace information.:blame_diff
- Should format a string of code.
Examples
For example, to format errors as red strings and everything else as is, you could define a formatter callback function like this:
formatter_callback = fn
:error_info, msg -> [:red, msg, :reset] |> IO.ANSI.format() |> IO.iodata_to_binary()
_key, value -> value
end
@type formatter_callback_diff_key() ::
:diff_delete
| :diff_delete_whitespace
| :diff_insert
| :diff_insert_whitespace
Key passed to a formatter callback to format a diff.
See formatter_callback/0
.
@type formatter_callback_info_key() ::
:extra_info
| :error_info
| :test_module_info
| :test_info
| :location_info
| :stacktrace_info
| :blame_diff
Key passed to a formatter callback to format information.
See formatter_callback/0
.
@type id() :: term()
@type test() :: ExUnit.Test.t()
@type times_us() :: %{ run: pos_integer(), async: pos_integer() | nil, load: pos_integer() | nil }
The times spent on several parts of the test suite.
The following properties can be computed:
sync = run - (async || 0)
total = run + (load || 0)
async
is nil when there are no async tests.
load
is nil when the test suite is running and loading
tests concurrently.
@type width() :: non_neg_integer() | :infinity
Width for formatting.
For example, see format_assertion_diff/4
.
Functions
format_assertion_diff(assert_error, padding_size, width, formatter)
View Source@spec format_assertion_diff( ExUnit.AssertionError.t(), non_neg_integer(), width(), formatter_callback() ) :: keyword()
Formats ExUnit.AssertionError
diff.
It returns a keyword list with diffing information from the left and right side of the assertion, if any exists.
It expects the assertion error, the padding_size
for formatted content, the width (may be :infinity
),
and the formatter callback function.
Examples
iex> error = assert_raise ExUnit.AssertionError, fn -> assert [1, 2] == [1, 3] end
iex> formatter_cb = fn
...> :diff_enabled?, _ -> true
...> _key, value -> value
...> end
iex> keyword = format_assertion_diff(error, 5, 80, formatter_cb)
iex> for {key, val} <- keyword, do: {key, IO.iodata_to_binary(val)}
[left: "[1, 2]", right: "[1, 3]"]
Formats filters used to constrain cases to be run.
Examples
iex> format_filters([run: true, slow: false], :include)
"Including tags: [run: true, slow: false]"
iex> format_filters([list: [61, 62, 63]], :exclude)
"Excluding tags: [list: [61, 62, 63]]"
format_test_all_failure(test_module, failures, counter, width, formatter)
View Source@spec format_test_all_failure( ExUnit.TestModule.t(), [failure], non_neg_integer(), width(), formatter_callback() ) :: String.t() when failure: {atom(), term(), Exception.stacktrace()}
Receives a test module and formats its failure.
Examples
iex> failure = {:error, catch_error(raise "oops"), _stacktrace = []}
iex> formatter_cb = fn _key, value -> value end
iex> test_module = %ExUnit.TestModule{name: Hello}
iex> format_test_all_failure(test_module, [failure], 1, 80, formatter_cb)
" 1) Hello: failure on setup_all callback, all tests have been invalidated\n ** (RuntimeError) oops\n"
@spec format_test_failure( test(), [failure], non_neg_integer(), width(), formatter_callback() ) :: String.t() when failure: {atom(), term(), Exception.stacktrace()}
Receives a test and formats its failures.
Examples
iex> failure = {:error, catch_error(raise "oops"), _stacktrace = []}
iex> formatter_cb = fn _key, value -> value end
iex> test = %ExUnit.Test{name: :"it works", module: MyTest, tags: %{file: "file.ex", line: 7}}
iex> format_test_failure(test, [failure], 1, 80, formatter_cb)
" 1) it works (MyTest)\n file.ex:7\n ** (RuntimeError) oops\n"
Formats time taken running the test suite.
Examples
iex> format_times(%{run: 10000, async: nil, load: nil})
"Finished in 0.01 seconds (0.00s async, 0.01s sync)"
iex> format_times(%{run: 10000, async: nil, load: 20000})
"Finished in 0.03 seconds (0.02s on load, 0.00s async, 0.01s sync)"
iex> format_times(%{run: 10000, async: nil, load: 200_000})
"Finished in 0.2 seconds (0.2s on load, 0.00s async, 0.01s sync)"
iex> format_times(%{run: 100_000, async: 50000, load: 200_000})
"Finished in 0.3 seconds (0.2s on load, 0.05s async, 0.05s sync)"