0

我已经阅读了有关 EUnit 的文档,但我仍然不知道测试生成器的目的是什么。

我也在这里阅读了一个不错的教程,但仍然没有运气(有点太高级了)。

我有点理解测试生成器函数返回一组测试,然后由 EUnit 执行。(那正确吗?)

不幸的是,我现在唯一有信心的是我可以编写这样的测试:

myfun_test() ->
assertEqual(myresult,mymod:myfun()).

问题是:EUnit 中需要什么测试生成器,它们与简单测试对象有什么关系?

PS 我知道在各种自动化工具和概念的帮助下,有一个很棒的单元测试世界(示例),但我不知道如何进入它。

4

2 回答 2

2

我想如果你尝试为你的项目写过很多单元测试,你会在实践中发现测试生成器的价值。

如果使用测试生成器,您不需要花费时间来创建许多不同的测试函数名称,并且创建测试生成器的代码比标准函数短。

例如,以下代码来自gproc测试生成器的开源项目,它使用测试生成器供您参考,文件可以在github.

reg_test_() ->
    {setup,
     fun() ->
             application:start(gproc),
         application:start(mnesia)
     end,
     fun(_) ->
             application:stop(gproc),
         application:stop(mnesia)
     end,
     [
      {spawn, ?_test(?debugVal(t_simple_reg()))}
      , ?_test(t_is_clean())
      , {spawn, ?_test(?debugVal(t_simple_counter()))}
      , ?_test(t_is_clean())
      , {spawn, ?_test(?debugVal(t_simple_aggr_counter()))}
      , ?_test(t_is_clean())
      , {spawn, ?_test(?debugVal(t_update_counters()))}
      , ?_test(t_is_clean())
      , {spawn, ?_test(?debugVal(t_simple_prop()))}
      , ?_test(t_is_clean())
      , {spawn, ?_test(?debugVal(t_await()))}
      , ?_test(t_is_clean())
      , {spawn, ?_test(?debugVal(t_await_self()))}
      , ?_test(t_is_clean())
      , {spawn, ?_test(?debugVal(t_await_crash()))}
      , ?_test(t_is_clean())
      , {spawn, ?_test(?debugVal(t_simple_mreg()))}
      , ?_test(t_is_clean())
      , {spawn, ?_test(?debugVal(t_gproc_crash()))}
      , ?_test(t_is_clean())
      , {spawn, ?_test(?debugVal(t_cancel_wait_and_register()))}
      , ?_test(t_is_clean())
      , {spawn, ?_test(?debugVal(t_give_away_to_pid()))}
      , ?_test(t_is_clean())
      , {spawn, ?_test(?debugVal(t_give_away_to_self()))}
      , ?_test(t_is_clean())
      , {spawn, ?_test(?debugVal(t_give_away_badarg()))}
      , ?_test(t_is_clean())
      , {spawn, ?_test(?debugVal(t_give_away_to_unknown()))}
      , ?_test(t_is_clean())
      , {spawn, ?_test(?debugVal(t_give_away_and_back()))}
      , ?_test(t_is_clean())
      , {spawn, ?_test(?debugVal(t_select()))}
      , ?_test(t_is_clean())
      , {spawn, ?_test(?debugVal(t_select_count()))}
      , ?_test(t_is_clean())
      , {spawn, ?_test(?debugVal(t_qlc()))}
      , ?_test(t_is_clean())
      , {spawn, ?_test(?debugVal(t_get_env()))}
      , ?_test(t_is_clean())
      , {spawn, ?_test(?debugVal(t_get_set_env()))}
      , ?_test(t_is_clean())
      , {spawn, ?_test(?debugVal(t_set_env()))}
      , ?_test(t_is_clean())
      , {spawn, ?_test(?debugVal(t_get_env_inherit()))}
      , ?_test(t_is_clean())
      , {spawn, ?_test(?debugVal(t_monitor()))}
      , ?_test(t_is_clean())
      , {spawn, ?_test(?debugVal(t_monitor_give_away()))}
      , ?_test(t_is_clean())
      , {spawn, ?_test(?debugVal(t_subscribe()))}
      , ?_test(t_is_clean())
      , {spawn, ?_test(?debugVal(t_gproc_info()))}
      , ?_test(t_is_clean())
     ]}.
于 2012-05-16T22:53:10.163 回答
2

从您在问题中链接的页面阅读:

简单测试函数的一个缺点是您必须为每个测试用例编写一个单独的函数(具有单独的名称)。编写测试的一种更紧凑的方式(并且更灵活,正如我们将看到的)是编写返回测试的函数,而不是测试。

名称以 ... test () 结尾的函数(注意最后的下划线)被 EUnit 识别为测试生成器函数。测试生成器返回由 EUnit 执行的一组测试的表示。

考虑对生成器进行分组测试的可能性。除了拥有更紧凑的代码外,您还可以为测试提供高级功能。例如,您的一组测试的状态、初始化函数等等。

如果您的应用程序需要的只是一组断言,那么您可能不需要测试集。你甚至可以避免使用整个 EUnit。Erlang 中的模式匹配 (=) 运算符本身就是一个出色的测试运算符。相比:

assertEqual(myresult,mymod:myfun()).

和:

myresult = mymod:myfun()
于 2012-05-17T07:47:55.557 回答