【问题标题】:Erlang: How should I test this?Erlang:我应该如何测试这个?
【发布时间】:2023-03-19 17:57:01
【问题描述】:

我有一个应用程序,我将一条消息发送到 gen_server 以启动操作,然后我每秒调用 gen_server 以收集中间结果,直到操作完成。在生产中,它通常需要几分钟,但它只受输入大小的限制,我也想测试一个小时的操作。

我希望始终通过根据需要运行测试来确保此操作仍然有效。理想情况下,我还想用不同的输入多次运行这个测试。

我现在使用 eunit,但它似乎没有专门构建的方式来执行此场景。普通测试是否提供了这一点?有没有一种优雅的测试方法,或者我应该只是破解一些东西?一般来说,我在思考如何在 Erlang 中系统地测试有状态的异步操作时遇到了麻烦。

【问题讨论】:

  • 您没有显示任何代码供我们推理,因此我们无法真正告诉您如何测试它。一般来说,测试一些东西,查看覆盖率以找到你没有测试的东西,然后测试它。重复。
  • 废话。也许不能。幸运的是,我注意到有几个阅读 Erlang 标签的人能够有效地回答一般性问题。

标签: erlang


【解决方案1】:

是的,普通测试会这样做。

这是我们 erlang emacs 模式提供的通用测试套件骨架的精简版(您可以使用the normal erlang oneerlware one):

-module(junk).

%% Note: This directive should only be used in test suites.
-compile(export_all).

-include("test_server.hrl").

%%
%% set up for the suite...
%%
init_per_suite(Config) ->
    Config.

end_per_suite(_Config) ->
    ok.

%%
%% setup for each case in the suite - can know which test case it is in
init_per_testcase(_TestCase, Config) ->
    Config.

end_per_testcase(_TestCase, _Config) ->
    ok.

%%
%% allows the suite to be programmatically managed
%%
all(doc) ->
    ["Describe the main purpose of this suite"];

all(suite) ->
    [].

%% Test cases starts here.
%%--------------------------------------------------------------------
test_case(doc) ->
    ["Describe the main purpose of test case"];

test_case(suite) ->
    [];

test_case(Config) when is_list(Config) ->
    ok.

有两种基本方法可以做到。

首先在init_per_suite/1 中启动gen_server,然后对该长时间运行的服务器进行大量原子测试,然后在end_per_suite/1 中拆除gen_server。这是首选方式 - 您的 gen_server 应该在许多事务中长期运行和持久化,等等等等……

另一种方法是进行单例测试并使用init_per_testcase/2 启动gen_server 并在end_per_testcase/2 中将其拆除

【讨论】:

  • 我想我最大的问题是我需要任意数量的测试用例。可能需要 5、10、23 次或任意次数调用 gen_server 来检索所有结果。这可能吗?
  • 我想我可以递归地调用相同的测试用例函数,而不是将客户端到 gen_server 的每个结果请求视为一个单独的测试用例。如果允许,那应该是完美的。
  • 其实更好的解决方案是使用repeat-until-successful策略,重复测试(延迟1秒)直到得到最终结果。结合时间陷阱,这应该是理想的。
  • 我觉得我参与这个主题有点多余:) 继续努力!我建议你做的是在测试中放置一个循环,重复直到成功,但可能在套件中进行 1 分钟、10 分钟和 1 小时的测试..
【解决方案2】:

用任何语言测试有状态的异步操作都很困难,无论是 Erlang 还是其他语言。

我实际上建议使用 etap 并让异步测试运行一个回调,然后运行 ​​etap:end_tests()

由于etap 使用正在运行的测试服务器并等待 end_test 调用,因此您对异步测试有更多的控制权。

【讨论】:

  • 邪恶!感谢您构建这个。我试试看。
  • 我开始了它,但 Nick Gerakines 已经从最初的开始走了很长的路。他也应该得到相当多的赞誉。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多