[Erl_Question05]gen_server怎么去写eunit?

来源:转载

Prework:

  怎样写一个基本的Eunit? Doc.

1. 加入头文件:声明此模块以”_test”结尾的函数都是测试用,并在编译时自动在这个模块里加入test()函数(当然这个可以用宏来控制)

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

2.编写测试用例:”*_test()”函数":

reverse_nil_test() -> [] = lists:reverse([]).

reverse_one_test() -> [1] = lists:reverse([1]).

reverse_two_test() -> [2,1] = lists:reverse([1,2]).

%%也可以用宏:这个有好几种,很方便,要用就看文档,比不用宏的优势在于出错信息详细

length_test() -> ?assert(length([1,2,3]) =:= 3).

3. 运行 Eunit

  编译Module –> 然后:

Module:test().

%%

eunit:test(Module).

以上是一个最简单的Eunit的例子,那么:

Question: 类似gen_server有启动进程类的Eunit怎么写?有并发的怎么写?

基本Code形式:

-ifdef(TEST).

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

-compile({no_auto_import, [get/1, put/2]}).

basic_test_() ->

{setup,

fun() ->

?debugFmt("Starting ~p", [?MODULE]),

case start_link() of

{error, {already_started, _}} ->

ok;

{ok, _} ->

do_stop

end

end,

fun(Stop) ->

case Stop of

do_stop -> stop();

ok -> ok

end

end,

[

{timeout, 60, fun normal_insert/0},

{timeout, 60, fun ttl_insert/0}

]

}.

noraml_insert() ->

todo.

ttl_insert() ->

todo.

-endif.

Eunit提供以下格式:

%%To make the descriptions simpler, we first list some definitions:

Setup () -> (R::any())

SetupX (X::any()) -> (R::any())

Cleanup (R::any()) -> any()

CleanupX (X::any(), R::any()) -> any()

Instantiator ((R::any()) -> Tests) | {with, [AbstractTestFun::((any()) -> any())]}

Where local | spawn | {spawn, Node::atom()}

Table .1: (these are explained in more detail further below.)

%%The following representations specify fixture handling for test sets:

{setup, Setup, Tests | Instantiator}

{setup, Setup, Cleanup, Tests | Instantiator}

{setup, Where, Setup, Tests | Instantiator}

{setup, Where, Setup, Cleanup, Tests | Instantiator}

Setup () -> (R::any())

SetupX (X::any()) -> (R::any())

Cleanup (R::any()) -> any()

CleanupX (X::any(), R::any()) -> any()

Instantiator ((R::any()) -> Tests) | {with, [AbstractTestFun::((any()) -> any())]}

Where local | spawn | {spawn, Node::atom()}

我们上面就是用的: {setup,Setup,Cleanup,TestList}这种,所以用Setup启动,运行TestList后用启动Setup的返回值传入Cleanup(Val)结束!注意这个test一定是xxx_test_()的形式,注意最后的_ 

可以看出_test_()的范围比_test()的大,但是限定为fun() –> end.

Tip: 如果你想用新起进程来测试一个模块【gen_server是不需要这样子的,本来就是新起了个进程】可以参照Where参数。

通过以上,我们就可以写出很漂亮的gen_server的enuit函数啦!!

 

那么如何让多个enuit并行跑呢?比如不相关的几个gen_server并行跑起来!

用参数:inparallel

base_test_() ->

{setup, spawn,

fun() -> start() end,

fun(_) -> stop() end,

{inparallel, 3,[

{timeout, 60, funnormal_insert/0},

{timeout, 60, ttl_insert/0}

]}

}.

惊喜:可以指定同时跑几个哦,上面指定了3个,不指定也可以的.

========================================================

一个好的application一定要有可靠的测试用例!,但是如果你在程序里面大量用有副作用的进程字典,还是很难写enuit的…


分享给朋友:
您可能感兴趣的文章:
随机阅读: