我有一个测试套件,我需要知道该项目的覆盖范围。
我玩过mix test --cover
,但发现native erlang's coverage analysis tool充其量是不够的。
本机覆盖率工具不会告诉您分支覆盖率或功能覆盖率。唯一的指标似乎是相关行,我不知道它们是如何计算的。就我所知,这只是测试覆盖率的最基本形式:请查看是否执行了给定的文本行。
我尝试了Coverex,但结果是灾难性的。它不仅遭受与本机工具相同的问题,而且由于将导入的模块视为未经测试,因此似乎也无法产生正确的结果。
也许它做得很好,并且我的代码未经测试,但是我不确定,因为它没有告诉我如何它正在评估我的代码< / em>。文件覆盖率达到40%?我想念什么?我不知道,该工具不会告诉我。
我现在正在使用ExCoveralls。它比以前的选项要好得多,它使我可以轻松配置要忽略的文件夹,但是它使用本机覆盖工具,因此同样存在很多问题。
我希望能在伊斯坦布尔(或者在这种情况下为nyc
)中找到一些东西:
https://github.com/istanbuljs/nyc
测试覆盖率分析告诉我我需要了解的所有信息,指标以及所有信息:
分支,函数,行,语句,所有您需要知道的都在那里。
答案 0 :(得分:2)
本机覆盖工具在源代码,记录模块,函数,arity,子句号和行号的每一行上插入“撞车”调用:
bump_call(Vars, Line) ->
A = erl_anno:new(0),
{call,A,{remote,A,{atom,A,ets},{atom,A,update_counter}},
[{atom,A,?COVER_TABLE},
{tuple,A,[{atom,A,?BUMP_REC_NAME},
{atom,A,Vars#vars.module},
{atom,A,Vars#vars.function},
{integer,A,Vars#vars.arity},
{integer,A,Vars#vars.clause},
{integer,A,Line}]},
{integer,A,1}]}.
如the cover documentation中所述,您可以覆盖模块,函数,函数子句和行。看起来ExCoveralls在其报告中仅使用行覆盖,但没有理由不能完全覆盖这四种类型的覆盖。
不支持分支覆盖。似乎要支持分支机构覆盖范围,就需要扩展“凹凸”记录并更新cover.erl
以记录该信息。除非有人这样做,否则只有当分支出现在不同的行上时,覆盖范围信息才是准确的。例如:
case always_false() of
true ->
%% this line shows up as not covered
do_something();
false ->
ok
end.
%% this line shows up as covered, even though do_something is never called
always_false() andalso do_something()
答案 1 :(得分:0)
要给@legoscia做出出色的回应,我还想澄清为什么 cover 不进行陈述评估。根据官方论坛中的讨论:
https://elixirforum.com/t/code-coverage-tools-for-elixir/18102/10
首先将代码编译为erlang,然后从erlang编译为修改后的二进制文件(但不会创建.beam
文件),该文件会自动加载到内存中并执行。
由于erlang代码的工作方式,单个语句可以包含多个指令:
单行可能会导致多个VM“声明”,例如:
Integer.to_string(a + 1)
将通过2条指令得出结果:
{line,[{location,"lib/tasks.ex",6}]}.
{gc_bif,'+',{f,0},1,[{x,0},{integer,1}],{x,0}}.
{line,[{location,"lib/tasks.ex",6}]}.
{call_ext_only,1,{extfunc,erlang,integer_to_binary,1}}.
因此,对于自动分析工具而言,提供语句覆盖率非常棘手,因为很难将语句与指令匹配,尤其是在理论上,只要结果相同,编译器就可以随意对命令进行重新排序。