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
它的测试覆盖率分析告诉我我需要知道的一切,指标和所有:
分支、函数、行、语句,你需要知道的一切都在那里。
问题
- 是否有任何工具使用 Istanbul 通过 Elixir 而不是原生的 erlang 来衡量代码覆盖率?
- 如果没有,有没有办法配置原生覆盖工具来给我更多信息?
- 原生覆盖率工具使用哪些指标?
本机覆盖工具在源代码的每一行、记录模块、函数、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}]}.
如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}}.
因此,自动分析工具提供语句覆盖是相当棘手的,因为很难将语句与指令匹配,特别是理论上编译器可以随意重新排序命令,只要结果是一样。
背景
我有一个测试套件,我需要知道项目的覆盖范围。
我玩过 mix test --cover
但我发现 native erlang's coverage analysis tool 充其量是不够的。
本机覆盖工具不会告诉您有关分支覆盖或函数覆盖的信息。唯一的指标似乎是相关行,我不知道它们是如何计算的。据我所知,这只是最基本的测试覆盖形式:查看是否执行了给定的文本行。
你试过什么?
我试过Coverex,但结果很糟糕。它不仅会遇到与本机工具相同的问题,而且似乎不会产生正确的结果,因为它将导入的模块计为未经测试。
或者也许它做得很好而我的代码没有经过很好的测试,但我不能确定,因为它没有告诉我如何 它正在评估我的代码。文件中有 40% 的覆盖率?我错过了什么?我不知道,工具不会告诉我。
我现在正在使用 ExCoveralls。它比以前的选项好得多,它允许我轻松配置我想忽略的文件夹,但是它使用本机覆盖工具,所以它遇到了同样的问题。
你想要什么?
我希望在伊斯坦布尔的线路中找到一些东西,或者在这种情况下 nyc
:
https://github.com/istanbuljs/nyc
它的测试覆盖率分析告诉我我需要知道的一切,指标和所有:
分支、函数、行、语句,你需要知道的一切都在那里。
问题
- 是否有任何工具使用 Istanbul 通过 Elixir 而不是原生的 erlang 来衡量代码覆盖率?
- 如果没有,有没有办法配置原生覆盖工具来给我更多信息?
- 原生覆盖率工具使用哪些指标?
本机覆盖工具在源代码的每一行、记录模块、函数、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}]}.
如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}}.
因此,自动分析工具提供语句覆盖是相当棘手的,因为很难将语句与指令匹配,特别是理论上编译器可以随意重新排序命令,只要结果是一样。