【问题标题】:How to do unit test coverage in Erlang如何在 Erlang 中进行单元测试覆盖
【发布时间】:2013-07-08 03:28:49
【问题描述】:

在使用 Python 时,我使用 python-coverage 之类的工具测试代码覆盖率,特别是对于 django 包 djaango-nose,我正在寻找 Erlang 中的等价物。我已经用eunit 进行了测试,并用surefire 生成了我的报告,但是我没有找到一种方法来进行代码覆盖,有人知道这样做的工具或方法吗?

【问题讨论】:

    标签: testing erlang code-coverage eunit


    【解决方案1】:

    我已经使用 common test 来控制测试套件,然后在测试规范中您可以使用元组 {cover,"coverspec path"} 声明一个覆盖规范:

    {include, ["../include"]}.
    {suites,"../test", all}.
    {logdir,"../results"}.
    {cover,"../test/reduce.coverspec"}.
    

    cover spec主要定义了详细程度和要分析的模块列表:

    {level, details}.
    {incl_mods, [calc,calc_store]}.
    

    然后,当您运行测试时,您会得到一个增量网页,其中包含完成的所有测试迭代,以及每个结果和覆盖率摘要的链接,然后您的源代码带有时间数量的注释评估了一条线。

    以及带注释的来源:

    File generated from d:/documents and Settings/xxxxxxx/My Documents/git/calc/ebin/../src/calc_store.erl by COVER 2012-06-01 at 10:23:45
    
    ****************************************************************************
    
            |  -module(calc_store).
            |  
            |  -behaviour(gen_server).
            |  
            |  -record(state,{var,func}).
            |  -define(SERVER,?MODULE).
            |  
            |  %% gen_server call back
            |  -export([code_change/3,handle_call/3,handle_cast/2,handle_info/2,init/1,terminate/2]).
            |  
            |  %% api
            |  -export([start_link/0,storevar/2,storefunc/4,getvalue/1,getfunc/1,stop/0]).
            |  
            |  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
            |  
            |  storevar(Name,Value) ->
         1..|      gen_server:cast(?MODULE,{storevar,Name,Value}).
            |  
            |  storefunc(Name,Par,Desc,Text) ->
         3..|      gen_server:cast(?MODULE,{storefunc,Name,Par,Desc,Text}).
            |  
            |  getvalue(Name) ->
        67..|      gen_server:call(?MODULE,{readvar,Name}).
            |  
            |  getfunc(Name) ->
        10..|      gen_server:call(?MODULE,{readfunc,Name}).
            |  
            |  stop() ->
         0..|   gen_server:cast(?MODULE,stop).
            |  
            |  start_link() -> 
         1..|      gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
            |  
            |  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
            |  
            |  init([]) -> 
            |      %% register(?MODULE,self()),
         1..|      {ok,#state{var=dict:new(),func=dict:new()}}.
            |  
            |  handle_call({readvar,Name}, _From, State = #state{var=D}) -> 
        67..|      Reply = dict:find(Name,D), 
        67..|      {reply, Reply, State};
            |  handle_call({readfunc,Name}, _From, State = #state{func=F}) -> 
        10..|      Reply = dict:find(Name,F) , 
        10..|      {reply, Reply, State};
            |  handle_call(Request, From, State) -> 
         0..|      io:format("calc_store received call: ~p from ~p~n",[Request,From]),
         0..|      Reply = ok, 
         0..|      {reply, Reply, State}.
            |  
            |  handle_cast(stop,State) ->
         0..|   {stop,State};
            |  handle_cast({storevar,Name,Value}, State = #state{var=D}) -> 
         1..|      NewD= dict:store(Name,Value,D),
         1..|      {noreply, State#state{var=NewD}};
            |  handle_cast({storefunc,Name,Par,Desc,Text}, State = #state{func=F}) -> 
         3..|      NewF= dict:store(Name,{Par,Desc,Text},F),
         3..|      {noreply, State#state{func=NewF}};
            |  handle_cast(Msg, State) -> 
         0..|      io:format("calc_store received cast: ~p~n",[Msg]),
         0..|      {noreply, State}.
            |  
            |  handle_info({'EXIT',_P,shutdown},State) -> 
         0..|      {stop,State};
            |  handle_info(Msg,State) -> 
         0..|      io:format("calc_state received info: ~p~n",[Msg]),
         0..|      {noreply,State}.
            |  
            |  terminate(_Reason, _State) -> 
         0..|      ok.
            |  
            |  code_change(_OldVsn, State, _Extra) -> 
         0..|      {ok, State}.
    

    【讨论】:

    • 嘿,我们实际上是在尝试使用 rebar2 运行我们的 EUnit 测试,您知道是否可以在没有通用测试的情况下获得覆盖率数据?
    • 我从未听说过 rebar2。如果您说的是 rebar3,则可以使用选项 {cover_enabled, true} 并使用命令 rebar3 eunit --cover 运行测试来使用测试覆盖率功能。见rebar3。但我还没用过。
    • 谢谢!它在工作。 :)
    【解决方案2】:

    如果您是 rebar,请添加:

    {cover_enabled, true}.
    

    致您的rebar.config

    【讨论】:

    • 我没有使用 rebar,因为它尚未在 Debian 中打包,最好不要在没有打包的情况下安装它,感谢您的回答
    猜你喜欢
    • 2011-03-14
    • 2016-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多