1

在编写测试时,我发现自己编写了各种小的辅助函数来进行断言。我搜索了一个断言库,但没有找到任何东西。在我的测试中,我经常有这样的事情:

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())or 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()).

所以我的问题是:

  • 为什么 Common Test 没有断言库?
  • 是否有可能构建一个在所有测试期间都可以访问的第三方库?
4

4 回答 4

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一旦您的测试用例运行,它将被终止,因为您链接到每个测试用例的进程。

所以答案是:断言是内置的。因此对断言库的需求较少。

于 2014-07-03T20:40:49.660 回答
1

在旁注中,在签名中编写模式匹配中的第一个块而不是添加一个案例更简洁和更有效。

value_in_list(_Value, []           ) -> false;
value_in_list( Value, [Value|List] ) -> true;
value_in_list( Value, [ _   |List] ) -> value_in_list(Value, List).

我意识到这可能只是对原始问题的评论,但是如果没有等宽和换行符,这将很难阅读。

于 2014-07-06T22:26:39.893 回答
1

您可以在 Common Test 中使用 EUnit 断言。

-include_lib("eunit/include/eunit.hrl").

并且所有常规断言都是可用的。

于 2014-07-15T15:21:11.683 回答
1

我决定编写一个Erlang 断言库来帮助解决这样的情况。它提供了这个功能。

于 2014-11-21T16:03:38.423 回答