4

我是 erlang 的初学者,我编写了一个基本的 gen 服务器程序,如下所示,我想知道如何测试服务器,以便我知道它运行良好。

-module(gen_server_test).
-behaviour(gen_server).
-export([start_link/0]).
-export([alloc/0, free/1]).
-export([init/1, handle_call/3, handle_cast/2]).
start_link() ->
    gen_server:start_link({local, gen_server_test}, ch3, [], []).
alloc() ->
    gen_server:call(gen_server_test, alloc).
free(Ch) ->
    gen_server:cast(gen_server_test, {free, Ch}).
init(_Args) ->
    {ok, channels()}.
handle_call(alloc, _From, Chs) ->
    {Ch, Chs2} = alloc(Chs),
    {reply, Ch, Chs2}.
handle_cast({free, Ch}, Chs) ->
    io:format(Ch),
        io:format(Chs),
        Chs2 = free(),
    {noreply, Chs2}.

free() -> 
        io:format("free").
channels() ->
        io:format("channels").
alloc(chs) -> 
        io:format("alloc chs").

顺便说一句:程序可以编译,它不是一个好的程序,我只是想打印一些东西以确保它可以工作:)

4

2 回答 2

8

gen_server 实现模块的美妙之处在于它只是一个回调模块。甚至不需要产生底层的 gen_server 进程来测试它。

您需要做的就是让您的测试框架(通常是 eunit)通过向其注入不同的输入(不同的 gen_server 状态、不同的输入消息)等来调用所有的 handle_call/cast/info 函数,并确保它返回正确的响应元组(例如 {reply, ok, NewState} 或 {noreply, NewState} 等)

当然,如果您的回调函数不是纯函数,这将无法完美运行。例如,在您的 handle_call 函数中,如果您正在向另一个进程发送消息,或者您正在修改 ets 表。在这种情况下,您必须确保在运行测试之前预先创建了所有必需的进程和表。

于 2011-05-06T07:49:05.423 回答
2

您可以尝试以下方法之一:

  1. 使用 erlang shell 并手动调用命令。确保源文件或 .beam 文件位于 Erlang 路径中​​(参数-pz,如下所示erl -pz <path here>:)

  2. 编写一个 EUnit 测试用例

PS:我认为您的代码有错误,因为您似乎将模块ch3作为服务器启动,而不是gen_server_test模块。

于 2011-05-06T06:50:43.227 回答