查看源代码 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_delta
和 assert_raise
,以便轻松处理其他常见情况,例如检查浮点数或处理异常。
概要
函数
断言其参数为真值。
断言 value
为真值,否则显示给定的 message
。
断言 value1
和 value2
之间的差值不超过 delta
。
断言在 function
执行期间会引发 exception
。返回已恢复的异常,否则失败。
断言在指定的 timeout
时间段内(以毫秒为单位)会收到与 pattern
匹配的消息。
断言已收到与 pattern
匹配的消息,并且该消息位于当前进程的邮箱中。
断言 expression
将导致错误。
断言 expression
将退出。
断言 expression
将抛出值。
使用消息失败。
否定断言,预期表达式为 false
或 nil
。
断言 value
为 nil
或 false
(即 value
不是真值)。
断言 value1
和 value2
之间的差值不在 delta
内。
断言在指定的 timeout
时间段内(以毫秒为单位)未收到(并且不会收到)与 pattern
匹配的消息。
断言未收到与 pattern
匹配的消息(即该消息不在当前进程的邮箱中)。
函数
断言其参数为真值。
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()
断言 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, _}"
断言 value1
和 value2
之间的差值不超过 delta
。
此差异是包含性的,因此如果差异和 delta
相等,则测试将通过。
示例
assert_in_delta 1.1, 1.5, 0.2
assert_in_delta 10, 15, 2
assert_in_delta 10, 15, 5
断言在 function
执行期间会引发 exception
。返回已恢复的异常,否则失败。
示例
assert_raise ArithmeticError, fn ->
1 + "test"
end
assert_raise RuntimeError, fn ->
raise "assertion will pass due to this raise"
end
断言在 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
断言在指定的 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}
断言已收到与 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, _}
断言 expression
将导致错误。
返回错误,否则失败。
示例
assert catch_error(error(1)) == 1
断言 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}
断言 expression
将抛出值。
返回已抛出的值,否则失败。
示例
assert catch_throw(throw(1)) == 1
使用消息失败。
示例
flunk("This should raise an error")
否定断言,预期表达式为 false
或 nil
。
请记住,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
断言 value
为 nil
或 false
(即 value
不是真值)。
示例
refute true, "This will obviously fail"
断言 value1
和 value2
之间的差值不在 delta
内。
此差异是排他的,因此如果差异和 delta 相等,则测试将失败。
如果您提供 message
,有关这些值的信息将自动追加到其中。
示例
refute_in_delta 1.1, 1.2, 0.2
refute_in_delta 10, 11, 2
断言在指定的 timeout
时间段内(以毫秒为单位)未收到(并且不会收到)与 pattern
匹配的消息。
pattern
参数必须是匹配模式。如果收到与 pattern
匹配的消息,则使用 failure_message
失败。
示例
refute_receive :bye
使用显式超时时间反驳已收到
refute_receive :bye, 1000
断言未收到与 pattern
匹配的消息(即该消息不在当前进程的邮箱中)。
pattern
参数必须是匹配模式。如果收到与 pattern
匹配的消息,则使用 failure_message
失败。
超时时间设置为 0,因此没有等待时间。
示例
send(self(), :hello)
refute_received :bye
send(self(), :hello)
refute_received :hello, "Oh No!"
** (ExUnit.AssertionError) Oh No!