在编写测试时,我发现自己编写了各种小的辅助函数来进行断言。我搜索了一个断言库,但没有找到任何东西。在我的测试中,我经常会遇到这样的事情:
value_in_list(_Value, []) ->
false;
value_in_list(Value, [Item|List]) ->
case Value == Item of
true ->
true;
false ->
value_in_list(Value, List)
end.
test_start_link(_Config) ->
% should return the pid and register the process as my_app
{ok, Pid} = my_app:start_link(),
true = is_pid(Pid),
value_in_list(my_app, registered()).
我最终必须编写一个完整的函数来检查my_app是否是一个注册过程。如果我可以调用类似assertion:value_in_list(my_app, registered())
或assertion:is_registered(my_app)
的内容,那会更好。
我来自Ruby背景,所以我讨厌用实用函数混淆我的测试只是为了做一些断言。如果我能这样做会更清洁:
test_start_link(_Config) ->
% should return the pid and register the process as my_app
{ok, Pid} = my_app:start_link(),
true = is_pid(Pid),
assertion:value_in_list(my_app, registered()).
所以我的问题是:
答案 0 :(得分:1)
将您的应用程序启动移至套件的启动部分:
init_per_suite(Config) ->
{ok, Pid} = my_app:start_link(),
true = is_pid(Pid),
[{app, Pid} | Config].
然后将您的测试注册写为:
test_registration(Config) ->
Pid = ?config(app, Config),
true = lists:member(Pid, registered()).
没有必要通过显式断言函数来断言事物,因为它们是"内置于"。只需进行如上所述的失败匹配,测试过程就会崩溃。因此报告测试用例出错了。每个测试用例都在自己的进程中运行。这也是您想要在init_per_suite/1
回调中启动应用程序的原因。否则,一旦您的测试用例运行,my_app
将被终止,因为您链接到每个测试用例的过程。
所以答案是:内置断言。因此对断言库的需求就越少。
答案 1 :(得分:1)
另一方面,在签名中的模式匹配中编写第一个块是比较简洁和高效的,而不是添加案例。
value_in_list(_Value, [] ) -> false;
value_in_list( Value, [Value|List] ) -> true;
value_in_list( Value, [ _ |List] ) -> value_in_list(Value, List).
我意识到这可能只是对原始问题的评论,但如果没有等宽线和新线,那就很难阅读。
答案 2 :(得分:1)
您可以在Common Test中使用EUnit断言。
-include_lib("eunit/include/eunit.hrl").
所有常规断言都可用。
答案 3 :(得分:1)
我决定写一个Erlang assertion library来帮助处理这类案件。它提供此功能。