Unit testing 为什么不存在用于公共测试的第三方断言库?

Unit testing 为什么不存在用于公共测试的第三方断言库?,unit-testing,erlang,assertion,common-test,Unit Testing,Erlang,Assertion,Common Test,在编写测试时,我发现自己编写了各种各样的小助手函数来进行断言。我搜索了一个断言库,没有找到任何东西。在我的测试中,我经常有这样的事情: value_in_list(_Value, []) -> false; value_in_list(Value, [Item|List]) -> case Value == Item of true -> true; false -> value_in_list(Value, List)

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

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()).
最后,我不得不编写一个完整的函数来检查我的应用程序是否是注册进程。如果我可以调用类似于
assertion:value\u in\u list(我的\u应用程序,registed())
assertion:is\u registed(我的\u应用程序)
,那就更好了

我有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()).
因此,我的问题是:

  • 为什么公共测试不存在断言库
  • 是否有可能构建一个在所有测试期间都可以访问的第三方库
这方面的一些想法: 将应用程序启动移动到套件的启动部分:

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\u per\u suite/1
回调中启动应用程序的原因。否则,
my_app
将在您的测试用例运行后终止,因为您已链接到每个测试用例的进程

所以答案是:断言是内置的。因此,对断言库的需求就更少了。

对此有一些想法: 将应用程序启动移动到套件的启动部分:

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\u per\u suite/1
回调中启动应用程序的原因。否则,
my_app
将在您的测试用例运行后终止,因为您已链接到每个测试用例的进程


所以答案是:断言是内置的。因此,不需要像这样的断言库。

另一方面,在签名的模式匹配中写入第一个块比添加大小写更简洁、更高效

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

我意识到这可能只是对原始问题的一个评论,但如果没有单空格和换行符,阅读起来非常困难。

另一方面,在签名中的模式匹配中写入第一个块比添加一个案例更简洁、更有效

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

我意识到这可能只是对原始问题的一个评论,但如果没有单空格和换行符,阅读起来非常困难。

您可以在公共测试中使用EUnit断言

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

所有常规断言都可用。

您可以在公共测试中使用EUnit断言

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

所有的常规断言都可用。

我决定写一篇文章来帮助处理这样的案例。它提供了这种功能。

我决定写一篇文章来帮助处理这样的案例。它提供了这一功能。

与普通测试无关,但我想说的是,如果您想做出断言,就应该使用EUnit。EUnit提供了大量断言宏(虽然不包括is_registered case;相反,您必须执行类似于
?assert(列出:member(my_app,registered())
)的操作)另外,请查看Berzemus的答案(以及LYSE的链接)这里,因为它解释了EUnt和普通测试的不同用例:也许我误用了断言。我只是指当某个东西返回一个意外的值时会引发异常。例如,在上面的代码中,我会考虑<代码>真= ISPID(PID)。作为一个断言。如果
Pid
不是一个Pid,则会引发异常。实际上,考虑到这一点,没有必要对其进行测试。标准OTP测试应该确保这一点按预期进行。这可能是一个错误的示例选择。没有必要测试进程是否已注册。我正在尝试演示评估这样一个事实:我们经常需要使用辅助函数来混乱测试,以确定我们正在测试的函数是否按照我们预期的方式工作。与普通测试无关,但我想说,如果您想进行断言,则应该使用EUnit。EUnit提供了大量断言宏(虽然不包括已注册的案例;相反,您必须执行类似于
?assert(列出:member(my_app,registered())
)的操作)另外,请查看Berzemus的答案(以及LYSE的链接)这里,因为它解释了EUnt和普通测试的不同用例:也许我误用了断言。我只是指当某个东西返回一个意外的值时会引发异常。例如,在上面的代码中,我会考虑<代码>真= ISPID(PID)。作为一个断言。如果
Pid
不是一个Pid,则会引发异常。实际上,考虑到这一点,没有必要对其进行测试。标准OTP测试应该确保这一点按预期进行。这可能是一个错误的示例选择。没有必要测试进程是否已注册。我正在尝试演示评价这样一个事实:我们经常需要用助手函数来混乱我们的测试,以确定我们正在测试的函数是否按照我们预期的方式工作。这并不能回答这个问题。要评论或要求作者澄清,请在他们的帖子下方留下评论。凯,对不起,我基本上不使用堆栈溢出我不太了解当地的规则。在这种语言中,这是一个主要的性能差异。我