查看源代码 ExUnit.Assertions (ExUnit v1.16.2)

此模块包含一组断言函数,这些函数默认情况下会被导入到您的测试用例中。

通常,开发人员希望在测试中使用通用的 assert 宏。此宏会检查您的代码,并在出现错误时提供良好的报告。例如,assert some_fun() == 10 将失败(假设 some_fun() 返回 13

Comparison (using ==) failed in:
code:  assert some_fun() == 10
left:  13
right: 10

此模块还提供了其他便利函数,例如 assert_in_deltaassert_raise,以便轻松处理其他常见情况,例如检查浮点数或处理异常。

概要

函数

断言其参数为真值。

断言 value 为真值,否则显示给定的 message

断言 value1value2 之间的差值不超过 delta

断言在 function 执行期间会引发 exception。返回已恢复的异常,否则失败。

断言在 function 执行期间会引发 exception,并带有预期的 message,该消息可以是 Regex 或精确的 String。返回已恢复的异常,否则失败。

断言在指定的 timeout 时间段内(以毫秒为单位)会收到与 pattern 匹配的消息。

断言已收到与 pattern 匹配的消息,并且该消息位于当前进程的邮箱中。

断言 expression 将导致错误。

断言 expression 将退出。

断言 expression 将抛出值。

使用消息失败。

否定断言,预期表达式为 falsenil

断言 valuenilfalse(即 value 不是真值)。

断言 value1value2 之间的差值不在 delta 内。

断言在指定的 timeout 时间段内(以毫秒为单位)未收到(并且不会收到)与 pattern 匹配的消息。

断言未收到与 pattern 匹配的消息(即该消息不在当前进程的邮箱中)。

函数

链接到此宏

assert(assertion)

查看源代码 (宏)

断言其参数为真值。

assert 会检查底层表达式,并在出现错误时提供良好的报告。例如,如果表达式使用比较运算符,则消息将显示两边的值。断言

assert 1 + 2 + 3 + 4 > 15

将使用以下消息失败

Assertion with > failed
code:  assert 1 + 2 + 3 + 4 > 15
left:  10
right: 15

类似地,如果给出了匹配表达式,它将报告与该匹配相关的任何错误。给定

assert [1] = [2]

您将看到

match (=) failed
code:  assert [1] = [2]
left: [1]
right: [2]

请记住,assert 不会根据表达式更改其语义。换句话说,表达式仍然需要返回真值。例如,以下将失败

assert nil = some_function_that_returns_nil()

即使匹配有效,assert 仍然需要真值。在这种情况下,只需使用 ==/2match?/2

链接到此函数

assert(value, message)

查看源代码

断言 value 为真值,否则显示给定的 message

示例

assert false, "it will never be true"

assert x == :foo, "expected x to be foo"

assert match?({:ok, _}, x), "expected x to match {:ok, _}"
链接到此函数

assert_in_delta(value1, value2, delta, message \\ nil)

查看源代码

断言 value1value2 之间的差值不超过 delta

此差异是包含性的,因此如果差异和 delta 相等,则测试将通过。

示例

assert_in_delta 1.1, 1.5, 0.2
assert_in_delta 10, 15, 2
assert_in_delta 10, 15, 5
链接到此函数

assert_raise(exception, function)

查看源代码

断言在 function 执行期间会引发 exception。返回已恢复的异常,否则失败。

示例

assert_raise ArithmeticError, fn ->
  1 + "test"
end

assert_raise RuntimeError, fn ->
  raise "assertion will pass due to this raise"
end
链接到此函数

assert_raise(exception, message, function)

查看源代码

断言在 function 执行期间会引发 exception,并带有预期的 message,该消息可以是 Regex 或精确的 String。返回已恢复的异常,否则失败。

示例

assert_raise ArithmeticError, "bad argument in arithmetic expression", fn ->
  1 + "test"
end

assert_raise RuntimeError, ~r/^today's lucky number is 0\.\d+!$/, fn ->
  raise "today's lucky number is #{:rand.uniform()}!"
end
链接到此宏

assert_receive(pattern, timeout \\ nil, failure_message \\ nil)

查看源代码 (宏)

断言在指定的 timeout 时间段内(以毫秒为单位)会收到与 pattern 匹配的消息。

assert_received 不同,它具有默认的 timeout,为 100 毫秒。

pattern 参数必须是匹配模式。如果未收到与 pattern 匹配的消息,则使用 failure_message 失败。

示例

assert_receive :hello

断言针对较长的超时时间

assert_receive :hello, 20_000

您还可以根据特定模式进行匹配

assert_receive {:hello, _}

x = 5
assert_receive {:count, ^x}
链接到此宏

assert_received(pattern, failure_message \\ nil)

查看源代码 (宏)

断言已收到与 pattern 匹配的消息,并且该消息位于当前进程的邮箱中。

pattern 参数必须是匹配模式。如果未收到与 pattern 匹配的消息,则使用 failure_message 失败。

超时时间设置为 0,因此没有等待时间。

示例

send(self(), :hello)
assert_received :hello

send(self(), :bye)
assert_received :hello, "Oh No!"
** (ExUnit.AssertionError) Oh No!

您还可以根据特定模式进行匹配

send(self(), {:hello, "world"})
assert_received {:hello, _}
链接到此宏

catch_error(expression)

查看源代码 (宏)

断言 expression 将导致错误。

返回错误,否则失败。

示例

assert catch_error(error(1)) == 1
链接到此宏

catch_exit(expression)

查看源代码 (宏)

断言 expression 将退出。

返回当前进程的退出状态/消息,否则失败。

示例

assert catch_exit(exit(1)) == 1

要断言从测试开始的链接进程退出,请使用 Process.flag/2 捕获退出,并使用 assert_receive/2 断言退出消息。

Process.flag(:trap_exit, true)
pid = spawn_link(fn -> Process.exit(self(), :normal) end)
assert_receive {:EXIT, ^pid, :normal}
链接到此宏

catch_throw(expression)

查看源代码 (宏)

断言 expression 将抛出值。

返回已抛出的值,否则失败。

示例

assert catch_throw(throw(1)) == 1
链接到此函数

flunk(message \\ "Flunked!")

查看源代码
@spec flunk(String.t()) :: no_return()

使用消息失败。

示例

flunk("This should raise an error")
链接到此宏

refute(assertion)

查看源代码 (宏)

否定断言,预期表达式为 falsenil

请记住,refute 不会更改给定表达式的语义。换句话说,以下将失败

refute {:ok, _} = some_function_that_returns_error_tuple()

上面的代码将失败,因为当两侧不匹配时,= 运算符总是会失败,而 refute/2 不会改变它。

编写上面反驳的正确方法是使用 match?/2

refute match?({:ok, _}, some_function_that_returns_error_tuple())

示例

refute age < 0
链接到此函数

refute(value, message)

查看源代码

断言 valuenilfalse(即 value 不是真值)。

示例

refute true, "This will obviously fail"
链接到此函数

refute_in_delta(value1, value2, delta, message \\ nil)

查看源代码

断言 value1value2 之间的差值不在 delta 内。

此差异是排他的,因此如果差异和 delta 相等,则测试将失败。

如果您提供 message,有关这些值的信息将自动追加到其中。

示例

refute_in_delta 1.1, 1.2, 0.2
refute_in_delta 10, 11, 2
链接到此宏

refute_receive(pattern, timeout \\ nil, failure_message \\ nil)

查看源代码 (宏)

断言在指定的 timeout 时间段内(以毫秒为单位)未收到(并且不会收到)与 pattern 匹配的消息。

pattern 参数必须是匹配模式。如果收到与 pattern 匹配的消息,则使用 failure_message 失败。

示例

refute_receive :bye

使用显式超时时间反驳已收到

refute_receive :bye, 1000
链接到此宏

refute_received(pattern, failure_message \\ nil)

查看源代码 (宏)

断言未收到与 pattern 匹配的消息(即该消息不在当前进程的邮箱中)。

pattern 参数必须是匹配模式。如果收到与 pattern 匹配的消息,则使用 failure_message 失败。

超时时间设置为 0,因此没有等待时间。

示例

send(self(), :hello)
refute_received :bye

send(self(), :hello)
refute_received :hello, "Oh No!"
** (ExUnit.AssertionError) Oh No!