View Source ExUnit (ExUnit v1.17.2)
Unit testing framework for Elixir.
Example
A basic setup for ExUnit is shown below:
# File: assertion_test.exs
# 1) Start ExUnit.
ExUnit.start()
# 2) Create a new test module (test case) and use "ExUnit.Case".
defmodule AssertionTest do
# 3) Note that we pass "async: true", this runs the test case
# concurrently with other test cases. The individual tests
# within each test case are still run serially.
use ExUnit.Case, async: true
# 4) Use the "test" macro instead of "def" for clarity.
test "the truth" do
assert true
end
end
To run the tests above, run the file using elixir
from the
command line. Assuming you named the file assertion_test.exs
,
you can run it as:
$ elixir assertion_test.exs
Case, Callbacks and Assertions
See ExUnit.Case
and ExUnit.Callbacks
for more information
about defining test cases and setting up callbacks.
The ExUnit.Assertions
module contains a set of macros to
generate assertions with appropriate error messages.
Integration with Mix
Mix is the project management and build tool for Elixir. Invoking mix test
from the command line will run the tests in each file matching the pattern
*_test.exs
found in the test
directory of your project.
You must create a test_helper.exs
file inside the
test
directory and put the code common to all tests there.
The minimum example of a test_helper.exs
file would be:
# test/test_helper.exs
ExUnit.start()
Mix will load the test_helper.exs
file before executing the tests.
It is not necessary to require
the test_helper.exs
file in your test
files. Run mix help test
for more information.
Summary
Types
The error state returned by ExUnit.Test
and ExUnit.TestModule
All tests start with a state of nil
.
A map representing the results of running a test suite
Functions
Sets a callback to be executed after the completion of a test suite.
Starts tests asynchronously while test cases are still loading.
Awaits for a test suite that has been started with async_run/0
.
Returns ExUnit configuration.
Configures ExUnit.
Fetches the test supervisor for the current test.
Returns the pluralization for word
.
Registers a pluralization
for word
.
Runs the tests. It is invoked automatically
if ExUnit is started via start/1
.
Starts ExUnit and automatically runs tests right before the VM terminates.
Types
@type failed() :: [{Exception.kind(), reason :: term(), Exception.stacktrace()}]
The error state returned by ExUnit.Test
and ExUnit.TestModule
@type state() :: nil | {:excluded, binary()} | {:failed, failed()} | {:invalid, ExUnit.TestModule.t()} | {:skipped, binary()}
All tests start with a state of nil
.
A finished test can be in one of five states:
- Passed (also represented by
nil
) - Failed
- Skipped (via @tag :skip)
- Excluded (via :exclude filters)
- Invalid (when setup_all fails)
@type suite_result() :: %{ excluded: non_neg_integer(), failures: non_neg_integer(), skipped: non_neg_integer(), total: non_neg_integer() }
A map representing the results of running a test suite
Functions
@spec after_suite((suite_result() -> any())) :: :ok
Sets a callback to be executed after the completion of a test suite.
Callbacks set with after_suite/1
must accept a single argument, which is a
map containing the results of the test suite's execution.
If after_suite/1
is called multiple times, the callbacks will be called in
reverse order. In other words, the last callback set will be the first to be
called.
@spec async_run() :: Task.t()
Starts tests asynchronously while test cases are still loading.
It returns a task that must be given to await_run/0
when a result
is desired.
@spec await_run(Task.t()) :: suite_result()
Awaits for a test suite that has been started with async_run/0
.
@spec configuration() :: Keyword.t()
Returns ExUnit configuration.
For the available configuration options, see configure/1
.
@spec configure(Keyword.t()) :: :ok
Configures ExUnit.
Options
ExUnit supports the following options:
:assert_receive_timeout
- the timeout to be used onassert_receive
calls in milliseconds, defaults to100
;:autorun
- if ExUnit should run by default on exit. Defaults totrue
;:capture_log
- if ExUnit should default to keeping track of log messages and print them on test failure. Can be overridden for individual tests via@tag capture_log: false
. This can also be configured to a specific level withcapture_log: [level: LEVEL]
, to capture all logs but only keep those aboveLEVEL
. Note thaton_exit
andsetup_all
callbacks may still log, as they run outside of the testing process. To silent those, you can useExUnit.CaptureLog.capture_log/2
or consider disabling logging altogether.:colors
- a keyword list of color options to be used by some formatters::enabled
- boolean option to enable colors, defaults toIO.ANSI.enabled?/0
;:success
- success message (defaults to:green
):invalid
- invalid test message (defaults to:yellow
):skipped
- skipped test message (defaults to:yellow
):failure
- failed test message (defaults to:red
):error_info
- display of actual error (defaults to:red
):extra_info
- additional information (defaults to:cyan
):location_info
- filename and tags (defaults to[:bright, :black]
):diff_insert
- color of the insertions on diffs, defaults to:green
;:diff_insert_whitespace
- color of the whitespace insertions on diffs, defaults toIO.ANSI.color_background(2, 0, 0)
;:diff_delete
- color of the deletions on diffs, defaults to:red
;:diff_delete_whitespace
- color of the whitespace deletions on diffs, defaults toIO.ANSI.color_background(0, 2, 0)
;
:exclude
- specifies which tests are run by skipping tests that match the filter. See the "Filters" section in the documentation forExUnit.Case
;:exit_status
- specifies an alternate exit status to use when the test suite fails. Defaults to 2;:failures_manifest_path
- specifies a path to the file used to store failures between runs;:formatters
- the formatters that will print results, defaults to[ExUnit.CLIFormatter]
;:include
- specifies which tests are run by skipping tests that do not match the filter. Keep in mind that all tests are included by default, so unless they are excluded first, the:include
option has no effect. To only run the tests that match the:include
filter, exclude the:test
tag first (see the documentation forExUnit.Case
for more information on tags and filters);:max_cases
- maximum number of tests to run in parallel. Only tests from different modules run in parallel. It defaults toSystem.schedulers_online * 2
to optimize both CPU-bound and IO-bound tests;:max_failures
- the suite stops evaluating tests when this number of test failures is reached. All tests within a module that fail when using thesetup_all/1,2
callbacks are counted as failures. Defaults to:infinity
;:only_test_ids
- a list of{module_name, test_name}
tuples that limits what tests get run. This is typically used by Mix to filter which tests should run;:rand_algorithm
- algorithm to be used when generating the test seed. Available algorithms can be found in Erlang's:rand
documentation (see:rand.builting_arg/0
). Available since v1.16.0. Before v1.16.0, the algorithm was hard-coded to:exs1024
. On Elixir v1.16.0 and after, the default changed to:exsss
;:refute_receive_timeout
- the timeout to be used onrefute_receive
calls in milliseconds, defaults to100
;:seed
- an integer seed value to randomize the test suite. This seed is also mixed with the test module and name to create a new unique seed on every test, which is automatically fed into the:rand
module. This provides randomness between tests, but predictable and reproducible results. A:seed
of0
will disable randomization and the tests in each file will always run in the order that they were defined in;:slowest
- prints timing information for the N slowest tests. Running ExUnit with slow test reporting automatically runs intrace
mode. It is disabled by default;:slowest_modules
- prints timing information for the N slowest test modules. Running ExUnit with slow test reporting automatically runs intrace
mode. It is disabled by default;:stacktrace_depth
- configures the stacktrace depth to be used on formatting and reporters, defaults to20
;:timeout
- sets the timeout for the tests in milliseconds, defaults to60_000
;:trace
- sets ExUnit into trace mode, this sets:max_cases
to1
and prints each test case and test while running. Note that in trace mode test timeouts will be ignored as timeout is set to:infinity
;:test_location_relative_path
- the test location is the file:line information printed by tests as a shortcut to run a given test. When this value is set, the value is used as a prefix for the test itself. This is typically used by Mix to properly set-up umbrella projects;
Any arbitrary configuration can also be passed to configure/1
or start/1
,
and these options can then be used in places such as custom formatters. These
other options will be ignored by ExUnit itself.
@spec fetch_test_supervisor() :: {:ok, pid()} | :error
Fetches the test supervisor for the current test.
Returns {:ok, supervisor_pid}
or :error
if not called from the test process.
This is the same supervisor as used by ExUnit.Callbacks.start_supervised/2
and similar, see ExUnit.Callbacks
module documentation for more information.
Returns the pluralization for word
.
If one is not registered, returns the word appended with an "s".
Registers a pluralization
for word
.
If one is already registered, it is replaced.
@spec run([module()]) :: suite_result()
Runs the tests. It is invoked automatically
if ExUnit is started via start/1
.
From Elixir v1.14, it accepts an optional list of modules to run as part of the suite. This is often used to rerun modules already loaded in memory.
Returns a map containing the total number of tests, the number of failures, the number of excluded tests and the number of skipped tests.
@spec start(Keyword.t()) :: :ok
Starts ExUnit and automatically runs tests right before the VM terminates.
It accepts a set of options
to configure ExUnit
(the same ones accepted by configure/1
).
If you want to run tests manually, you can set the :autorun
option
to false
and use run/0
to run tests.