Assertions v0.15.0 Assertions View Source

Helpful assertions with great error messages to help you write better tests.

Link to this section Summary

Functions

Asserts that the return value of the given expression is true

Asserts that all maps, structs or keyword lists in list have the same value for key

Asserts that some condition succeeds within a given timeout (in milliseconds) and sleeps for a given time between checks of the given condition (in milliseconds)

Asserts that the file at path is changed to match comparison after executing the given expression

Asserts that the file at path is created after executing the given expression

Asserts that the file at path is deleted after executing the given expression

Asserts that two lists contain the same elements without asserting they are in the same order

Asserts that two lists contain the same elements without asserting they are in the same order

Asserts that a map is in the given list

Asserts that two maps are equal

Asserts that a function should raise an exception, but without forcing the user to specify which exception should be raised. This is essentially a less-strict version of assert_raise/2

Tests that a message matching the given pattern, and only that message, is received before the given timeout, specified in milliseconds

Asserts that the struct is present in the list

Asserts that two structs are equal

Asserts that the return value of the given expression is false

Link to this section Types

Link to this type

comparison() View Source
comparison() :: (any(), any() -> boolean() | no_return())

Link to this section Functions

Link to this macro

assert!(assertion) View Source (macro)
assert!(Macro.expr()) :: true | no_return()

Asserts that the return value of the given expression is true.

This is different than the normal behavior of assert since that will pass for any value that is "truthy" (anything other than false or nil). This is a stricter assertion, only passing if the value is true. This is very helpful for testing values that are expected to only be booleans.

This will also check specifically for nil values when using >, <, >= or <= since those frequently have unintended behavior.

iex> assert!(:a == :a)
true
iex> assert!(10 > 5)
true
iex> map = %{key: true}
iex> assert!(map.key)
true
Link to this macro

assert_all_have_value(list, key, value) View Source (macro)
assert_all_have_value([map() | struct() | Keyword.t()], any(), any()) ::
  true | no_return()

Asserts that all maps, structs or keyword lists in list have the same value for key.

iex> assert_all_have_value([%{key: :value}, %{key: :value, other: :key}], :key, :value)
true

iex> assert_all_have_value([[key: :value], [key: :value, other: :key]], :key, :value)
true

iex> assert_all_have_value([[key: :value], %{key: :value, other: :key}], :key, :value)
true
Link to this macro

assert_async(opts \\ [], expression) View Source (macro)
assert_async(Keyword.t(), Macro.expr()) :: true | no_return()

Asserts that some condition succeeds within a given timeout (in milliseconds) and sleeps for a given time between checks of the given condition (in milliseconds).

This is helpful for testing that asynchronous operations have succeeded within a certain timeframe. This method of testing asynchronous operations is less reliable than other methods, but it can often be more useful at an integration level.

iex> Process.send_after(self(), :hello, 50)
iex> assert_async do
iex>   assert_received :hello
iex> end
true

iex> Process.send_after(self(), :hello, 50)
iex> assert_async(timeout: 75, sleep_time: 40) do
iex>   assert_received :hello
iex> end
true

iex> Process.send_after(self(), :hello, 50)
iex> try do
iex>   assert_async(timeout: 4, sleep_time: 2) do
iex>     assert_received :hello
iex>   end
iex> rescue
iex>   _ -> :failed
iex> end
:failed
Link to this macro

assert_changes_file(path, comparison, expression) View Source (macro)
assert_changes_file(Path.t(), String.t() | Regex.t(), Macro.expr()) ::
  true | no_return()

Asserts that the file at path is changed to match comparison after executing the given expression.

If the file matches comparison before executing expr, this assertion will fail. The file does not have to exist before executing expr in order for this assertion to pass.

iex> path = Path.expand("../tmp/file.txt", __DIR__)
iex> result = assert_changes_file(path, "hi") do
iex>   File.mkdir_p!(Path.dirname(path))
iex>   File.write(path, "hi")
iex> end
iex> File.rm_rf!(Path.dirname(path))
iex> result
true
Link to this macro

assert_creates_file(path, expression) View Source (macro)
assert_creates_file(Path.t(), Macro.expr()) :: true | no_return()

Asserts that the file at path is created after executing the given expression.

iex> path = Path.expand("../tmp/file.txt", __DIR__)
iex> File.mkdir_p!(Path.dirname(path))
iex> result = assert_creates_file path do
iex>   File.write(path, "hi")
iex> end
iex> File.rm_rf!(Path.dirname(path))
iex> result
true
Link to this macro

assert_deletes_file(path, expression) View Source (macro)
assert_deletes_file(Path.t(), Macro.expr()) :: true | no_return()

Asserts that the file at path is deleted after executing the given expression.

iex> path = Path.expand("../tmp/file.txt", __DIR__)
iex> File.mkdir_p!(Path.dirname(path))
iex> File.write(path, "hi")
iex> assert_deletes_file path do
iex>   File.rm_rf!(Path.dirname(path))
iex> end
true
Link to this macro

assert_lists_equal(left, right) View Source (macro)
assert_lists_equal(list(), list()) :: true | no_return()

Asserts that two lists contain the same elements without asserting they are in the same order.

iex> assert_lists_equal([1, 2, 3], [1, 3, 2])
true
Link to this macro

assert_lists_equal(left, right, comparison) View Source (macro)
assert_lists_equal(list(), list(), comparison()) :: true | no_return()

Asserts that two lists contain the same elements without asserting they are in the same order.

The given comparison function determines if the two lists are considered equal.

iex> assert_lists_equal(["dog"], ["cat"], &(is_binary(&1) and is_binary(&2)))
true
Link to this macro

assert_map_in_list(map, list, keys_or_comparison) View Source (macro)
assert_map_in_list(map(), [map()], [any()]) :: true | no_return()
assert_map_in_list(map(), [map()], comparison()) :: true | no_return()

Asserts that a map is in the given list.

This is either done by passing a list of keys, and the values at those keys will be compared to determine if the map is in the list.

iex> map = %{first: :first, second: :second}
iex> list = [%{first: :first, second: :second, third: :third}]
iex> keys = [:first, :second]
iex> assert_map_in_list(map, list, keys)
true

Or this is done by passing a comparison function that determines if the map is in the list.

If using a comparison function, the map is the first argument to that function, and the elements in the list are the second argument.

iex> map = %{first: :first, second: :second}
iex> list = [%{"first" => :first, "second" => :second, "third" => :third}]
iex> comparison = &(&1.first == &2["first"] and &1.second == &2["second"])
iex> assert_map_in_list(map, list, comparison)
true
Link to this macro

assert_maps_equal(left, right, keys_or_comparison) View Source (macro)
assert_maps_equal(map(), map(), [any()]) :: true | no_return()
assert_maps_equal(map(), map(), comparison()) :: true | no_return()

Asserts that two maps are equal.

Equality can be determined in two ways. First, by passing a list of keys. The values at these keys will be used to determine if the maps are equal.

iex> left = %{first: :first, second: :second, third: :third}
iex> right = %{first: :first, second: :second, third: :fourth}
iex> keys = [:first, :second]
iex> assert_maps_equal(left, right, keys)
true

The second is to pass a comparison function that returns a boolean that determines if the maps are equal. When using a comparison function, the first argument to the function is the left map and the second argument is the right map.

iex> left = %{first: :first, second: :second, third: :third}
iex> right = %{"first" => :first, "second" => :second, "third" => :fourth}
iex> comparison = &(&1.first == &2["first"] and &1.second == &2["second"])
iex> assert_maps_equal(left, right, comparison)
true
Link to this function

assert_raise(func) View Source
assert_raise((... -> any())) :: true | no_return()

Asserts that a function should raise an exception, but without forcing the user to specify which exception should be raised. This is essentially a less-strict version of assert_raise/2.

iex> assert_raise(fn -> 1 / 0 end)
true
iex> assert_raise(fn -> String.to_existing_atom("asleimflisesliseli") end)
true
Link to this macro

assert_receive_only(pattern, timeout \\ 100) View Source (macro)
assert_receive_only(Macro.expr(), non_neg_integer()) :: any() | no_return()

Tests that a message matching the given pattern, and only that message, is received before the given timeout, specified in milliseconds.

The optional second argument is a timeout for the receive to wait for the expected message, and defaults to 100ms.

Examples

iex> send(self(), :hello)
iex> assert_receive_only(:hello)
true

iex> send(self(), [:hello])
iex> assert_receive_only([_])
true

iex> a = :hello
iex> send(self(), :hello)
iex> assert_receive_only(^a)
true

iex> send(self(), :hello)
iex> assert_receive_only(a when is_atom(a))
iex> a
:hello

iex> send(self(), %{key: :value})
iex> assert_receive_only(%{key: value} when is_atom(value))
iex> value
:value

If a message is received after the assertion has matched a message to the given pattern, but the second message is received before the timeout, that second message is ignored and the assertion returns true.

This assertion only tests that the message that matches the given pattern was the first message in the process inbox, and that nothing was sent between the sending the message that matches the pattern and when assert_receive_only/2 was called.

iex> Process.send_after(self(), :hello, 20)
iex> Process.send_after(self(), :hello_again, 50)
iex> assert_receive_only(:hello, 100)
true
Link to this macro

assert_struct_in_list(struct, list, keys_or_comparison) View Source (macro)
assert_struct_in_list(struct(), [struct()], [atom()]) :: true | no_return()
assert_struct_in_list(struct(), [struct()], (struct(), struct() -> boolean())) ::
  true | no_return()

Asserts that the struct is present in the list.

There are two ways to make this comparison. First is to pass a list of keys to use to compare the struct to the structs in the list.

iex> now = DateTime.utc_now()
iex> list = [DateTime.utc_now(), Date.utc_today()]
iex> keys = [:year, :month, :day]
iex> assert_struct_in_list(now, list, keys)
true

The second way to use this assertion is to pass a comparison function.

When using a comparison function, the struct is the first argument to that function and the elements in the list will be the second argument.

iex> now = DateTime.utc_now()
iex> list = [DateTime.utc_now(), Date.utc_today()]
iex> assert_struct_in_list(now, list, &(&1.year == &2.year))
true
Link to this macro

assert_structs_equal(left, right, keys_or_comparison) View Source (macro)
assert_structs_equal(struct(), struct(), [atom()]) :: true | no_return()
assert_structs_equal(struct(), struct(), (any(), any() -> boolean())) ::
  true | no_return()

Asserts that two structs are equal.

Equality can be determined in two ways. First, by passing a list of keys. The values at these keys and the type of the structs will be used to determine if the structs are equal.

iex> left = DateTime.utc_now()
iex> right = DateTime.utc_now()
iex> keys = [:year, :minute]
iex> assert_structs_equal(left, right, keys)
true

The second is to pass a comparison function that returns a boolean that determines if the structs are equal. When using a comparison function, the first argument to the function is the left struct and the second argument is the right struct.

iex> left = DateTime.utc_now()
iex> right = DateTime.utc_now()
iex> comparison = &(&1.year == &2.year and &1.minute == &2.minute)
iex> assert_structs_equal(left, right, comparison)
true
Link to this macro

refute!(assertion) View Source (macro)
refute!(Macro.expr()) :: true | no_return()

Asserts that the return value of the given expression is false.

This is different than the normal behavior of refute/1 since that will pass if the value is either false or nil. This is a stricter assertion, only passing if the value is false. This is very helpful for testing values that are expected to only be booleans.

This will also check specifically for nil values when using >, <, >= or <= since those frequently have unintended behavior.

iex> refute!(5 > 10)
true
iex> refute!("a" == "A")
true