Erlang:我应该如何测试这个?

发布于 2024-08-18 06:35:23 字数 290 浏览 7 评论 0原文

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

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

我现在使用 eunit,但它似乎没有专门构建的方法来练习这个场景。普通测试是否提供了这一点?有没有一种优雅的方法来测试这个或者我应该破解一些东西?总的来说,我很难理解如何在 Erlang 中系统地测试有状态的异步操作。

I've got an application where I cast a message to a gen_server to start an operation, then I call the gen_server every second to gather intermediate results until the operation completes. In production, it usually takes a couple of minutes, but it's only limited by the input size and I'd like to test hour long operations, too.

I want to always make sure this operation still works by running a test as needed. Ideally, I'd like to run this test multiple times with different inputs, also.

I use eunit right now, but it doesn't seem to have a purpose-built way of exercising this scenario. Does commmon test provide for this? Is there an elegant way of testing this or should I just hack something up? In general, I'm having trouble wrapping my head around how to systematically test stateful, asynchronous operations in Erlang.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

↙厌世 2024-08-25 06:35:23

是的,普通测试就可以做到这一点。

这是我们的 erlang emacs 模式提供的通用测试套件框架的简化版本(您可以使用 普通的 erlang erlware ):

-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 中将其拆除

Yes, common test will do this.

This is a cut down version of the common test suite skeleton that our erlang emacs mode provides (you can use the normal erlang one or erlware 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.

There are 2 basic ways you could do it.

First up start the gen_server in init_per_suite/1 and then have a large number of atomic tests that act on that long running server and then tear the gen_server down in end_per_suite/1. This is the preferred way - your gen_server should be long-running and persistent over many transactions, blah-blah...

The other way is to make a singleton test and start the gen_server with init_per_testcase/2 and tear it down in end_per_testcase/2

安静 2024-08-25 06:35:23

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

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

由于 etap 使用正在运行的测试服务器并且它等待 end_test 调用,因此您可以更多地控制异步测试。

Testing Stateful Asynchronous operations is hard in any language, Erlang or otherwise.

I would actuall recommend using etap and have the asynchronous tests run a callback that will then run etap:end_tests()

Since etap uses a running test server and it waits for the end_test call you have a little more control for asynchronous tests.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文