zoukankan      html  css  js  c++  java
  • [Erlang05]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_()的形式,注意最后的_ 

    gen_server_enuit

    可以看出_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的…

  • 相关阅读:
    python基础学习(2)
    python基础语法
    面试常见问题(2)——数据库
    面试常见问题(1)——TCP协议
    python基础回顾(一)
    安装Beautiful Soup
    MongoDB的安装、配置和可视化
    神奇的斐波那契---解决兔子繁衍问题
    正规式、正规文法与自动机
    词法分析程序的设计与实现
  • 原文地址:https://www.cnblogs.com/zhongwencool/p/3729046.html
Copyright © 2011-2022 走看看