我有一个通用的测试套件,它试图创建一个ets表,用于所有套件和所有测试用例。它看起来像这样:
-module(an_example_SUITE).
-include_lib("common_test/include/ct.hrl").
-compile(export_all).
all() -> [ets_tests].
init_per_suite(Config) ->
TabId = ets:new(conns, [set]),
ets:insert(TabId, {foo, 2131}),
[{table,TabId} | Config].
end_per_suite(Config) ->
ets:delete(?config(table, Config)).
ets_tests(Config) ->
TabId = ?config(table, Config),
[{foo, 2131}] = ets:lookup(TabId, foo).
ets_tests
函数因badarg而失败。每个测试用例创建/销毁ets表,如下所示:
-module(an_example_SUITE).
-include_lib("common_test/include/ct.hrl").
-compile(export_all).
all() -> [ets_tests].
init_per_testcase(Config) ->
TabId = ets:new(conns, [set]),
ets:insert(TabId, {foo, 2131}),
[{table,TabId} | Config].
end_per_testcase(Config) ->
ets:delete(?config(table, Config)).
ets_tests(Config) ->
TabId = ?config(table, Config),
[{foo, 2131}] = ets:lookup(TabId, foo).
运行它,我发现它运行得很漂亮。
我对此行为感到困惑,无法确定为什么会发生这种情况,形成docs。问题:
答案 0 :(得分:3)
正如Pascal在答案中已经提到的那样,User Guide中仅讨论init_per_testcase
和end_per_testcase
在与测试用例相同的过程中运行。由于ETS表绑定到所有者进程,因此在整个套件或组中保留ETS表的唯一方法是将其放弃或定义继承进程。
您可以在init_per_suite
或init_per_group
函数中轻松生成一个进程,将其设置为ETS表的继承人,并在配置中传递其pid。
要清理所有您需要的是在end_per_suite
或end_per_group
函数中终止此过程。
-module(an_example_SUITE).
-include_lib("common_test/include/ct.hrl").
-compile(export_all).
all() -> [ets_tests].
ets_owner() ->
receive
stop -> exit(normal);
Any -> ets_owner()
end.
init_per_suite(Config) ->
Pid = spawn(fun ets_owner/0),
TabId = ets:new(conns, [set, protected, {heir, Pid, []}]),
ets:insert(TabId, {foo, 2131}),
[{table,TabId},{table_owner, Pid} | Config].
end_per_suite(Config) ->
?config(table_owner, Config) ! stop.
ets_tests(Config) ->
TabId = ?config(table, Config),
[{foo, 2131}] = ets:lookup(TabId, foo).
您还需要确保仍然可以通过protected
或public
答案 1 :(得分:0)
ets表附加到进程并在进程结束后立即销毁,除非你使用了give_away函数(在这种情况下我不担心这是不可行的)
作为common tets doc中的状态,每个测试用例和init_per_suite以及end_per_suite都在不同的进程中运行,因此只要离开init_per_suite函数就会销毁ets表。
fron common_test doc
init_per_suite和end_per_suite将在专用的Erlang上执行 过程,就像测试用例一样。这些功能的结果 但不包括在试运行成功统计中, 失败并跳过案件。
来自ets doc
默认所有者是创建表的进程。表 通过使用继承人,可以在流程终止时转移所有权 选项或通过调用give_away / 3明确显示。