CodeCoverage Elixir 的更多指标

More metrics for CodeCoverage Elixir

背景

我有一个测试套件,我需要知道项目的覆盖范围。 我玩过 mix test --cover 但我发现 native erlang's coverage analysis tool 充其量是不够的。

本机覆盖工具不会告诉您有关分支覆盖或函数覆盖的信息。唯一的指标似乎是相关行,我不知道它们是如何计算的。据我所知,这只是最基本的测试覆盖形式:查看是否执行了给定的文本行。

你试过什么?

我试过Coverex,但结果很糟糕。它不仅会遇到与本机工具相同的问题,而且似乎不会产生正确的结果,因为它将导入的模块计为未经测试。

或者也许它做得很好而我的代码没有经过很好的测试,但我不能确定,因为它没有告诉我如何 它正在评估我的代码。文件中有 40% 的覆盖率?我错过了什么?我不知道,工具不会告诉我。

我现在正在使用 ExCoveralls。它比以前的选项好得多,它允许我轻松配置我想忽略的文件夹,但是它使用本机覆盖工具,所以它遇到了同样的问题。

你想要什么?

我希望在伊斯坦布尔的线路中找到一些东西,或者在这种情况下 nyc:

https://github.com/istanbuljs/nyc

它的测试覆盖率分析告诉我我需要知道的一切,指标和所有:

分支、函数、行、语句,你需要知道的一切都在那里。

问题

  1. 是否有任何工具使用 Istanbul 通过 Elixir 而不是原生的 erlang 来衡量代码覆盖率?
  2. 如果没有,有没有办法配置原生覆盖工具来给我更多信息?
  3. 原生覆盖率工具使用哪些指标?

本机覆盖工具在源代码的每一行、记录模块、函数、arity、子句号和行号上插入 "bump" 调用:

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}]}.

(from cover.erl)

the cover documentation中所述,您可以获得模块、函数、函数子句和行的覆盖率。看起来 ExCoveralls 在其报告中只使用线覆盖,但没有理由不能使用所有四种类型的覆盖。

不支持分支覆盖。似乎支持分支覆盖需要扩展 "bump" 记录并更新 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()

添加到@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}}.

因此,自动分析工具提供语句覆盖是相当棘手的,因为很难将语句与指令匹配,特别是理论上编译器可以随意重新排序命令,只要结果是一样。