ExUnit v1.0.5 ExUnit.Case
Sets up an ExUnit test case.
This module must be used in other modules as a way to configure and prepare them for testing.
When used, it accepts the following options:
- :async - configure Elixir to run that specific test case in parallel with others. Must be used for performance when your test cases do not change any global state.
This module automatically includes all callbacks defined in
ExUnit.Callbacks
. See that module’s documentation for more
information.
Examples
defmodule AssertionTest do
# Use the module
use ExUnit.Case, async: true
# The `test` macro is imported by ExUnit.Case
test "always pass" do
assert true
end
end
Context
All tests receive a context as an argument. The context is particularly useful for sharing information between callbacks and tests:
defmodule KVTest do
use ExUnit.Case
setup do
{:ok, pid} = KV.start_link
{:ok, [pid: pid]}
end
test "stores key-values", context do
assert KV.put(context[:pid], :hello, :world) == :ok
assert KV.get(context[:pid], :hello) == :world
end
end
As the context is a map, it can be pattern matched on to extract information:
test "stores key-values", %{pid: pid} do
assert KV.put(pid, :hello, :world) == :ok
assert KV.get(pid, :hello) == :world
end
Tags
The context is used to pass information from the callbacks to the test. In order to pass information from the test to the callback, ExUnit provides tags.
By tagging a test, the tag value can be accessed in the context, allowing the developer to customize the test. Let’s see an example:
defmodule FileTest do
# Changing directory cannot be async
use ExUnit.Case, async: false
setup context do
# Read the :cd tag value
if cd = context[:cd] do
prev_cd = File.cwd!
File.cd!(cd)
on_exit fn -> File.cd!(prev_cd) end
end
:ok
end
@tag cd: "fixtures"
test "reads utf-8 fixtures" do
File.read("hello")
end
end
In the example above, we have defined a tag called :cd
that is
read in the setup callback to configure the working directory the
test is going to run on.
Tags are also very effective when used with case templates
(ExUnit.CaseTemplate
) allowing callbacks in the case template
to customize the test behaviour.
Note a tag can be set in two different ways:
@tag key: value
@tag :key # equivalent to setting @tag key: true
If a tag is given more than once, the last value wins.
Module tags
A tag can be set for all tests in a module by setting @moduletag
:
@moduletag :external
If the same key is set via @tag
, the @tag
value has higher
precedence.
Known tags
The following tags are set automatically by ExUnit and are therefore reserved:
:case
- the test case module:test
- the test name:line
- the line on which the test was defined:file
- the file on which the test was defined
The following tags customize how tests behaves:
:timeout
- customizes the test timeout in miliseconds (defaults to 30000)
Filters
Tags can also be used to identify specific tests, which can then
be included or excluded using filters. The most common functionality
is to exclude some particular tests from running, which can be done
via ExUnit.configure/1
:
# Exclude all external tests from running
ExUnit.configure(exclude: [external: true])
From now on, ExUnit will not run any test that has the external
flag
set to true. This behaviour can be reversed with the :include
option
which is usually passed through the command line:
mix test --include external:true
Run mix help test
for more information on how to run filters via Mix.
Another use case for tags and filters is to exclude all tests that have a particular tag by default, regardless of its value, and include only a certain subset:
ExUnit.configure(exclude: :os, include: [os: :unix])
Keep in mind that all tests are included by default, so unless they are
excluded first, the include
option has no effect.
Summary
Macros
Define a test with a string
Macros
Define a test with a string.
Provides a convenient macro that allows a test to be
defined with a string. This macro automatically inserts
the atom :ok
as the last line of the test. That said,
a passing test always returns :ok
, but, more importantly,
it forces Elixir to not tail call optimize the test and
therefore avoids hiding lines from the backtrace.
Examples
test "true is equal to true" do
assert true == true
end