cover
封面
模块
封面
模块摘要
Erlang覆盖分析工具
描述
该模块cover
为Erlang程序的覆盖率分析提供了一组函数,计算程序运行
时每个可执行
代码行
的执行
次数。
可执行行包含一个Erlang表达式,如匹配或函数调用。在case
- 或receive
语句中包含注释,函数头或模式的空行或行不可执行。
覆盖率分析可用于验证测试用例,确保涵盖所有相关代码,并且在查找代码中的瓶颈时也可能会有所帮助。
在进行任何分析之前,涉及的模块必须进行封面编译
。这意味着一些额外的信息在编译成二进制文件之前被添加到模块中,然后被加载。该模块的源文件不受影响,也没有.beam
创建文件。
每次调用Cover编译模块中的函数时,有关该调用的信息都会添加到Cover的内部数据库中。覆盖率分析是通过检查Cover数据库的内容来执行的。输出Answer
由两个参数确定,Level
和Analysis
。
Level = module
Answer = {Module,Value}
,Module
模块名称在哪里。
Level = function
Answer = [{Function,Value}]
,模块中每个函数的一个元组。一个函数由它的模块名M
,函数名F
和元A
组指定为一个元组{M,F,A}
。
Level = clause
Answer = [{Clause,Value}]
,模块中每个子句的一个元组。子句由其模块名称M
,函数名称F
,元素A
和在函数定义C
中的位置指定为元组{M,F,A,C}
。
Level = line
Answer = [{Line,Value}]
,模块中每个可执行行的一个元组。一行由它的模块名称M
和源文件中的行号指定N
为一个元组{M,N}
。
Analysis = coverage
Value = {Cov,NotCov}
其中Cov
是在已经执行至少一次,模块,函数,条款或者行可执行线的数量NotCov
是还没有被执行的可执行线的数目。
Analysis = calls
Value = Calls
这是模块,函数或子句被调用的次数。在生产线水平分析的情况下,生产Calls
线的执行次数。
分布
封面可以用于分布式Erlang系统。然后必须选择系统中的一个节点作为主节点
,并且必须从该节点执行所有Cover命令。not_main_node
如果在其中一个远程节点上调用接口函数,则返回错误原因。
使用cover:start/1
和cover:stop/1
添加或删除节点。在每个节点上加载相同的Cover编译代码,并且分析将收集并总结来自所有节点的覆盖数据结果。
要仅从远程节点收集数据而不停cover
在这些节点上,请使用cover:flush/1
如果到远程节点的连接断开,主节点将其标记为丢失。如果节点回来,它将被再次添加。如果远程节点在断开连接的周期中处于活动状态,则将在该周期之前和期间内的数据包含在分析中。
出口
start() -> {ok,Pid} | {error,Reason}
类型
启动拥有Cover内部数据库的Cover服务器。该功能由模块中的其他功能自动调用。
start(Nodes) -> {ok,StartedNodes} | {error,not_main_node}
类型
在每个给定节点上启动Cover服务器,并加载所有封面编译模块。
compile(ModFiles) -> Result | [Result]compile(ModFiles, Options) -> Result | [Result]compile_module(ModFiles) -> Result | [Result]compile_module(ModFiles, Options) -> Result | [Result]
类型
See `compile:file/2.`
编译模块进行封面分析。该模块由其模块名称Module
或其文件名给出File
。.erl
延伸部可以省略。如果模块位于另一个目录中,则必须指定路径。
Options
是默认的编译器选项列表[]
。只有定义包含文件目录和宏的选项被传递compile:file/2
,其他所有内容都被忽略。
如果该模块成功覆盖编译,则函数返回{ok,Module}
。否则函数返回{error,File}
。出现错误和警告时会进行打印。
如果一个列表ModFiles
是作为输入给出的,Result
则会返回一个列表。返回列表的顺序是未定义的。
请注意,内部数据库在编译过程中(重新)启动,这意味着之前收集的模块覆盖数据将会丢失。
compile_directory() -> [Result] | {error,Reason}compile_directory(Dir) -> [Result] | {error,Reason}compile_directory(Dir, Options) -> [Result] | {error,Reason}
类型
参见compile_module/1,2
参见compile_module/1,2
以相同的方式编译目录中的所有模块(.erl
文件)以Dir
进行封面分析,compile_module/1,2
并返回带有返回值的列表。
Dir
默认为当前工作目录。
{error,eacces}
如果目录不可读或{error,enoent}
目录不存在,则函数返回。
compile_beam(ModFiles) -> Result | [Result]
类型
与之相同compile/1,2
,但使用现有.beam
文件作为基础,即模块不是从源编译的。因此compile_beam/1
比...更快compile/1,2
。
请注意,现有.beam
文件必须包含抽象代码
,即它必须使用该debug_info
选项进行编译。如果不是,{no_abstract_code,BeamFile}
则返回错误原因。如果抽象代码
是加密的,并且没有密钥可用于解密,{encrypted_abstract_code,BeamFile}
则返回错误原因。
如果只有模块名称(即不是.beam
文件的全名)被赋予此函数,.beam
则通过调用找到该文件code:which(Module)
。如果找不到.beam
文件,non_existing
则返回错误原因。如果模块已经用编译器进行了覆盖编译compile_beam/1
,.beam
则会在第一次编译时从同一位置采集文件。如果模块已经用编译过的程序覆盖compile/1,2
,则无法找到正确的.beam
文件,因此{already_cover_compiled,no_beam_found,Module}
返回错误原因。
{error,BeamFile}
如果编译后的代码无法加载到节点上,则返回该值。
如果一个列表ModFiles
是作为输入给出的,Result
则会返回一个列表。返回列表的顺序是未定义的。
compile_beam_directory() -> [Result] | {error,Reason}compile_beam_directory(Dir) -> [Result] | {error,Reason}
类型
以相同的方式编译目录中的所有模块(.beam
文件)以Dir
进行封面分析,compile_beam/1
并返回带有返回值的列表。
Dir
默认为当前工作目录。
{error,eacces}
如果目录不可读或{error,enoent}
目录不存在,则函数返回。
analyse() -> {result,Ok,Fail} | {error,not_main_node}analyse(Modules) -> OneResult | {result,Ok,Fail} | {error,not_main_node}analyse(Analysis) -> {result,Ok,Fail} | {error,not_main_node}analyse(Level) -> {result,Ok,Fail} | {error,not_main_node}analyse(Modules, Analysis) -> OneResult | {result,Ok,Fail} | {error,not_main_node}analyse(Modules, Level) -> OneResult | {result,Ok,Fail} | {error,not_main_node}analyse(Analysis, Level) -> {result,Ok,Fail} | {error,not_main_node}analyse(Modules, Analysis, Level) -> OneResult | {result,Ok,Fail} | {error,not_main_node}
类型
执行的一个或多个覆盖编译的模块的分析,如通过指定Analysis
和Level
(见上文),通过检查所述内部数据库的内容。
Analysis
默认为coverage
并且Level
默认为function
。
如果Modules
是原子(一个模块),则返回将是OneResult
,否则返回将是{result,Ok,Fail}
。
如果Modules
没有给出,则分析在封面数据表中具有数据的所有模块。请注意,这包括封面编译的模块和导入的模块。
如果给定的模块不是Cover编译的,则由错误原因表示{not_cover_compiled,Module}
。
analyse_to_file() -> {result,Ok,Fail} | {error,not_main_node}analyse_to_file(Modules) -> Answer | {result,Ok,Fail} | {error,not_main_node}analyse_to_file(Options) -> {result,Ok,Fail} | {error,not_main_node}analyse_to_file(Modules,Options) -> Answer | {result,Ok,Fail} | {error,not_main_node}
类型
为给定模块创建源文件的副本,其中为每个可执行行指定其执行次数。
输出文件OutFile
默认为Module.COVER.out
,或者Module.COVER.html
如果使用该选项html
。
如果Modules
是原子(一个模块),返回将是Answer
,否则返回将是一个列表{result,Ok,Fail}
。
如果Modules
没有给出,则分析在封面数据表中具有数据的所有模块。请注意,这包括封面编译的模块和导入的模块。
如果某个模块不是Cover编译的,则由错误原因表示{not_cover_compiled,Module}
。
如果源文件和/或输出文件不能用打开file:open/2
,该函数返回{error,{file,File,Reason}}
这里File
是文件名,并Reason
为错误原因。
如果一个模块是由该.beam
文件编译的,例如使用compile_beam/1
or compile_beam_directory/0,1
,则假定源代码可以在与该.beam
文件相同的目录中找到,../src
相对于该目录或使用其中的源路径Module:module_info(compile)
。在使用后者时,检查两条路径:首先是通过连接构造的../src
路径src
,然后是编译后的路径本身,然后编译后的路径尾部。如果没有找到源代码,则由错误原因表示{no_source_code_found,Module}
。
async_analyse_to_file(Module) ->async_analyse_to_file(Module,Options) ->async_analyse_to_file(Module, OutFile) ->async_analyse_to_file(Module, OutFile, Options) -> pid()
类型
analyse_to_file
除了它是异步的而不是同步的,这个函数的工作方式与完全相同。生成的过程将在创建时与调用者链接。如果Error
在进行封面分析时出现问题,则进程将以与analyse_to_file
返回相同的错误原因崩溃。
modules() -> [Module] | {error,not_main_node}
类型
返回包含当前Cover编译的所有模块的列表。
imported_modules() -> [Module] | {error,not_main_node}
类型
返回包含导入数据的所有模块的列表。
imported() -> [File] | {error,not_main_node}
类型
返回包含所有导入文件的列表。
which_nodes() -> [Node] | {error,not_main_node}
类型
返回包含覆盖率分析一部分的所有节点的列表。请注意,当前节点不会返回。该节点始终是分析的一部分。
is_compiled(Module) -> {file,File} | false | {error,not_main_node}
类型
返回{file,File}
如果模块Module
被盖编译或false
以其他方式。File
是使用的.erl
文件cover:compile_module/1,2
或使用的.beam
文件compile_beam/1
。
reset(Module) ->reset() -> ok | {error,not_main_node}
类型
为Module
所有节点上封面数据库中的封装编译模块重置所有封面数据。如果省略参数,覆盖范围数据将为盖子已知的所有模块重置。
如果Module
不是Cover编译,则函数返回{error,{not_cover_compiled,Module}}
。
export(ExportFile)export(ExportFile,Module) -> ok | {error,Reason}
类型
将当前覆盖率数据导出Module
到文件ExportFile
。建议ExportFile
使用扩展名命名.coverdata
,因为其他文件名不能被基于Web的界面读取来覆盖。
如果Module
未提供,则导出所有Cover编译或先前导入的模块的数据。
如果要合并来自不同系统的覆盖率数据,此功能非常有用。
另请参阅 cover:import/1
import(ExportFile) -> ok | {error,Reason}
类型
从使用ExportFile
创建的文件导入覆盖率数据cover:export/1,2
。在此之后执行的任何分析都将包括导入的数据。
请注意,编译模块时,所有现有的覆盖率数据都将被删除
,包括导入的数据。如果在导入数据时已编译模块,则会将导入的数据添加
到现有覆盖率数据中。
可以将多个导出文件的覆盖率数据导入到一个系统中。覆盖数据然后在分析时相加。
除非模块首先被重置或编译,否则无法将模块的覆盖数据从同一文件导入两次。该检查基于文件名,因此您可以通过重命名导出文件轻松地欺骗系统。
另见cover:export/1,2
stop() -> ok | {error,not_main_node}
停止Cover服务器并卸载所有Cover编译代码。
stop(Nodes) -> ok | {error,not_main_node}
类型
停止Cover服务器并卸载给定节点上的所有Cover编译代码。存储在远程节点的Cover数据库中的数据被提取并存储在主节点上。
flush(Nodes) -> ok | {error,not_main_node}
类型
从远程节点上的掩护数据库中获取数据,并存储在主节点上。
另见
code(3), compile(3)