ExUnit.Callbacks
ExUnit.Callbacks
定义ExUnit回调。
这个模块定义了两个setup_all
和setup
回调以及on_exit/2
、start_supervised/2
和stop_supervised/1
功能。
设置回调是通过宏定义的,每个宏都可以选择接收包含元数据的映射,通常称为context
.回调可以选择将额外数据放入context
在测试中使用。
该setup_all
回调调用每个模块只有一次,任何测试运行之前。所有setup
回调都在每次测试之前运行。如果测试用例没有测试或所有测试已被过滤掉,则不会运行回调。
start_supervised/2
用于在主管下启动进程。主管与当前的测试过程相关联。在任何on_exit/2
回调运行之前,主管以及所有子进程都保证终止。
on_exit/2
回调是按需注册的,通常用于撤销设置回调执行的操作。on_exit/2
也可能需要参考,以便回调在将来被覆盖。已注册的on_exit/2
回调始终运行,而在失败时setup
和setup_all
停止所有剩余设置回调的执行。
最后,setup_all
回调函数在每个模块的单独进程中运行,而所有setup
回调函数都在与测试本身相同的进程中运行。on_exit/2
回调通常在一个单独的进程中运行,如名称所示。测试过程总是有理由退出:shutdown
,这意味着任何链接到测试过程的过程也将退出,尽管是异步的。因此最好start_supervised/2
用来保证同步终止。
下面是测试过程的生命周期的一个过程:
- 生成测试过程。
- 它运行
setup/2
回调
- 它自己运行测试。
- 它停止所有受监督的过程。
- 测试过程是有原因的:
:shutdown
on_exit/2
回调在单独的进程中执行。
语境
如果您返回关键字list,map或{:ok,关键字| map}中的关键字列表/地图将被合并到当前上下文中,并在所有后续的setup_all,setup和测试本身中可用。
同样,返回关键字列表,地图或{:ok,关键字| 来自设置的map}意味着返回的关键字列表/地图将被合并到当前上下文中,并且在所有后续设置和测试本身中都可用。
返回:ok 保持语境不变(都在setup和setup_all回调中)。
返回其他任何内容setup_all
都会强制所有测试失败,而来自错误的响应setup
会导致当前测试失败。
实例
defmodule AssertionTest do
use ExUnit.Case, async: true
# "setup_all" is called once per module before any test runs
setup_all do
IO.puts "Starting AssertionTest"
# No context is returned here
:ok
end
# "setup" is called before each test
setup do
IO.puts "This is a setup callback for #{inspect self()}"
on_exit fn ->
IO.puts "This is invoked once the test is done. Process: #{inspect self()}"
end
# Returns extra metadata to be merged into context
[hello: "world"]
end
# Same as above, but receives the context as argument
setup context do
IO.puts "Setting up: #{context.test}"
:ok
end
# Setups can also invoke a local or imported function that returns a context
setup :invoke_local_or_imported_function
test "always pass" do
assert true
end
test "uses metadata from setup", context do
assert context[:hello] == "world"
end
defp invoke_local_or_imported_function(context) do
[from_named_setup: true]
end
end
摘要
功能
on_exit(name_or_ref \ make_ref(),callback)
定义一个回调,该回调在测试退出后运行。
setup(block)
定义在每次测试之前要执行的回调
setup(var,block)
定义在每次测试之前要执行的回调
setup_all(block)
定义要在案例中的所有测试之前运行的回调
setup_all(var,block)
定义要在案例中的所有测试之前运行的回调
start_supervised(child_spec_or_module,opts \ [])
在测试主管下启动一个子进程
stop_supervised(id)
停止通过开始的子进程 start_supervised/2
功能
on_exit(name_or_ref \ make_ref(),回调)
on_exit(term, (() -> term)) :: :ok | no_return
定义一个回调,该回调将在测试退出后运行。
callback
是一个函数,它不接收参数,并在一个独立的进程中运行,而不是调用者。
on_exit/2
通常是从setup
和setup_all
回调,通常用于撤消在setup
然而,on_exit/2
也可以动态调用,其中可以使用引用来保证回调只调用一次。
setup(block) (macro)
定义要在每次测试之前运行的回调。
实例
setup :clean_up_tmp_directory
setup(var, block) (macro)
定义要在每次测试之前运行的回调。
实例
setup context do
[conn: Plug.Conn.build_conn()]
end
setup_all(block) (macro)
定义要在用例中的所有测试之前运行的回调。
实例
setup_all :clean_up_tmp_directory
setup_all(var, block) (macro)
定义要在用例中的所有测试之前运行的回调。
实例
setup_all context do
[conn: Plug.Conn.build_conn()]
end
start_supervised(child_spec_or_module,opts \ [])
start_supervised(Supervisor.child_spec | module | {module, term}, keyword) :: Supervisor.on_start_child
在测试主管下启动子进程。
它需要一个子规范或模块,类似于Supervisor.start_link/2
例如,如果应用程序通过运行以下命令启动监视树:
Supervisor.start_link([MyServer, {OtherSupervisor, ...}], ...)
您可以通过运行以下命令来独立地启动这些测试中的进程:
start_supervised(MyServer)
start_supervised{OtherSupervisor, :initial_value})
如果需要更改给定子进程的子规范,也可以提供关键字列表:
start_supervised{MyServer, :initial_value}, restart: :temporary)
见Supervisor
模块,讨论子规范和可用的规范密钥。
在测试管理器下启动进程的优点是,它保证在下一个测试开始之前退出。此外,由于子进程是受监督的,因此在发生崩溃时,将根据:restart
策略在子规范中,即使手动停止。因此,要保证从start_supervised/2
终止而不重新启动,请参见stop_supervised/1
...
如果成功,此函数返回{:ok, pid}
,否则它会返回{:error, reason}
...。
stop_supervised(ID)
stop_supervised(id :: term) :: :ok | {:error, :not_found}
停止通过start_supervised/2
...
这个函数期望id
在子规范中。例如:
{:ok, _} = start_supervised(MyServer)
:ok = stop_supervised(MyServer)
如果有监督的进程与这样的ID,它返回:ok,否则返回{:error, :not_found}