cover - A Coverage Analysis Tool for Erlang
The module cover provides a set of functions for coverage analysis of
Erlang programs, counting how many times each executable line of code
is executed when a program is run.
An executable line contains an Erlang expression such as a matching or
a function call. A blank line or a line containing a comment, function
head or pattern in a case- or receive statement is not executable.
Coverage analysis can be used to verify test cases, making sure all
relevant code is covered, and may also be helpful when looking for
bottlenecks in the code.
Before any analysis can take place, the involved modules must be Cover
compiled. This means that some extra information is added to the module
before it is compiled into a binary which then is loaded. The source
file of the module is not affected and no .beam file is created.
Each time a function in a Cover compiled module is called, information
about the call is added to an internal database of Cover. The coverage
analysis is performed by examining the contents of the Cover database.
The output Answer is determined by two parameters, Level and Analysis.
* Level = module
Answer = {Module,Value}, where Module is the module name.
* Level = function
Answer = [{Function,Value}], one tuple for each function in the
module. A function is specified by its module name M, function name
F and arity A as a tuple {M,F,A}.
* Level = clause
Answer = [{Clause,Value}], one tuple for each clause in the module.
A clause is specified by its module name M, function name F, arity
A and position in the function definition C as a tuple {M,F,A,C}.
* Level = line
Answer = [{Line,Value}], one tuple for each executable line in the
module. A line is specified by its module name M and line number in
the source file N as a tuple {M,N}.
* Analysis = coverage
Value = {Cov,NotCov} where Cov is the number of executable lines in
the module, function, clause or line that have been executed at
least once and NotCov is the number of executable lines that have
not been executed.
* Analysis = calls
Value = Calls which is the number of times the module, function, or
clause has been called. In the case of line level analysis, Calls
is the number of times the line has been executed.
Distribution
Cover can be used in a distributed Erlang system. One of the nodes in
the system must then be selected as the main node, and all Cover
commands must be executed from this node. The error reason
not_main_node is returned if an interface function is called on one of
the remote nodes.
Use cover:start/1 and cover:stop/1 to add or remove nodes. The same
Cover compiled code will be loaded on each node, and analysis will
collect and sum up coverage data results from all nodes.
To only collect data from remote nodes without stopping cover on those
nodes, use cover:flush/1
If the connection to a remote node goes down, the main node will mark
it as lost. If the node comes back it will be added again. If the
remote node was alive during the disconnected periode, cover data from
before and during this periode will be included in the analysis.
start() -> {ok,Pid} | {error,Reason}
Types:
Pid = pid()
Reason = {already_started,Pid}
Starts the Cover server which owns the Cover internal database.
This function is called automatically by the other functions in
the module.
start(Nodes) -> {ok,StartedNodes} | {error,not_main_node}
Types:
Nodes = StartedNodes = [atom()]
Starts a Cover server on the each of given nodes, and loads all
cover compiled modules.
compile(ModFiles) -> Result | [Result]
compile(ModFiles, Options) -> Result | [Result]
compile_module(ModFiles) -> Result | [Result]
compile_module(ModFiles, Options) -> Result | [Result]
Types:
ModFiles = ModFile | [ModFile]
ModFile = Module | File
Module = atom()
File = string()
Options = [Option]
Option = {i,Dir} | {d,Macro} | {d,Macro,Value} | export_all
See compile:file/2.
Result = {ok,Module} | {error,File} | {error,not_main_node}
Compiles a module for Cover analysis. The module is given by its
module name Module or by its file name File. The .erl extension
may be omitted. If the module is located in another directory,
the path has to be specified.
Options is a list of compiler options which defaults to []. Only
options defining include file directories and macros are passed
to compile:file/2, everything else is ignored.
If the module is successfully Cover compiled, the function
returns {ok,Module}. Otherwise the function returns
{error,File}. Errors and warnings are printed as they occur.
If a list of ModFiles is given as input, a list of Result will
be returned. The order of the returned list is undefined.
Note that the internal database is (re-)initiated during the
compilation, meaning any previously collected coverage data for
the module will be lost.
compile_directory() -> [Result] | {error,Reason}
compile_directory(Dir) -> [Result] | {error,Reason}
compile_directory(Dir, Options) -> [Result] | {error,Reason}
Types:
Dir = string()
Options = [Option]
See compile_module/1,2
Result = {ok,Module} | {error,File} | {error,not_main_node}
See compile_module/1,2
Reason = eacces | enoent
Compiles all modules (.erl files) in a directory Dir for Cover
analysis the same way as compile_module/1,2 and returns a list
with the return values.
Dir defaults to the current working directory.
The function returns {error,eacces} if the directory is not
readable or {error,enoent} if the directory does not exist.
compile_beam(ModFiles) -> Result | [Result]
Types:
ModFiles = ModFile | [ModFile]
ModFile = Module | BeamFile
Module = atom()
BeamFile = string()
Result = {ok,Module} | {error,BeamFile} | {error,Reason}
Reason = non_existing | {no_abstract_code,BeamFile} |
{encrypted_abstract_code,BeamFile} |
{already_cover_compiled,no_beam_found,Module} | not_main_node
Does the same as compile/1,2, but uses an existing .beam file as
base, i.e. the module is not compiled from source. Thus
compile_beam/1 is faster than compile/1,2.
Note that the existing .beam file must contain abstract code,
i.e. it must have been compiled with the debug_info option. If
not, the error reason {no_abstract_code,BeamFile} is returned.
If the abstract code is encrypted, and no key is available for
decrypting it, the error reason
{encrypted_abstract_code,BeamFile} is returned.
If only the module name (i.e. not the full name of the .beam
file) is given to this function, the .beam file is found by
calling code:which(Module). If no .beam file is found, the error
reason non_existing is returned. If the module is already cover
compiled with compile_beam/1, the .beam file will be picked from
the same location as the first time it was compiled. If the
module is already cover compiled with compile/1,2, there is no
way to find the correct .beam file, so the error reason
{already_cover_compiled,no_beam_found,Module} is returned.
{error,BeamFile} is returned if the compiled code can not be
loaded on the node.
If a list of ModFiles is given as input, a list of Result will
be returned. The order of the returned list is undefined.
compile_beam_directory() -> [Result] | {error,Reason}
compile_beam_directory(Dir) -> [Result] | {error,Reason}
Types:
Dir = string()
Result = See compile_beam/1
Reason = eacces | enoent
Compiles all modules (.beam files) in a directory Dir for Cover
analysis the same way as compile_beam/1 and returns a list with
the return values.
Dir defaults to the current working directory.
The function returns {error,eacces} if the directory is not
readable or {error,enoent} if the directory does not exist.
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}
Types:
Modules = Module | [Module]
Module = atom()
Analysis = coverage | calls
Level = line | clause | function | module
OneResult = {ok,{Module,Value}} | {ok,[{Item,Value}]} |
{error, Error}
Item = Line | Clause | Function
Line = {M,N}
Clause = {M,F,A,C}
Function = {M,F,A}
M = F = atom()
N = A = C = integer()
Value = {Cov,NotCov} | Calls
Cov = NotCov = Calls = integer()
Error = {not_cover_compiled,Module}
Ok = [{Module,Value}] | [{Item,Value}]
Fail = [Error]
Performs analysis of one or more Cover compiled modules, as
specified by Analysis and Level (see above), by examining the
contents of the internal database.
Analysis defaults to coverage and Level defaults to function.
If Modules is an atom (one module), the return will be
OneResult, else the return will be {result,Ok,Fail}.
If Modules is not given, all modules that have data in the cover
data table, are analysed. Note that this includes both cover
compiled modules and imported modules.
If a given module is not Cover compiled, this is indicated by
the error reason {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}
Types:
Modules = Module | [Module]
Module = atom()
OutFile = OutDir = string()
Options = [Option]
Option = html | {outfile,OutFile} | {outdir,OutDir}
Answer = {ok,OutFile} | {error,Error}
Ok = [OutFile]
Fail = [Error]
Error = {not_cover_compiled,Module} | {file,File,Reason} |
{no_source_code_found,Module}
File = string()
Reason = term()
Makes copies of the source file for the given modules, where it
for each executable line is specified how many times it has been
executed.
The output file OutFile defaults to Module.COVER.out, or
Module.COVER.html if the option html was used.
If Modules is an atom (one module), the return will be Answer,
else the return will be a list, {result,Ok,Fail}.
If Modules is not given, all modules that have data in the cover
data table, are analysed. Note that this includes both cover
compiled modules and imported modules.
If a module is not Cover compiled, this is indicated by the
error reason {not_cover_compiled,Module}.
If the source file and/or the output file cannot be opened using
file:open/2, the function returns {error,{file,File,Reason}}
where File is the file name and Reason is the error reason.
If a module was cover compiled from the .beam file, i.e. using
compile_beam/1 or compile_beam_directory/0,1, it is assumed that
the source code can be found in the same directory as the .beam
file, in ../src relative to that directory, or using the source
path in Module:module_info(compile). When using the latter, two
paths are examined: first the one constructed by joining ../src
and the tail of the compiled path below a trailing src
component, then the compiled path itself. If no source code is
found, this is indicated by the error reason
{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()
Types:
Module = atom()
OutFile = string()
Options = [Option]
Option = html
Error = {not_cover_compiled,Module} | {file,File,Reason} |
{no_source_code_found,Module} | not_main_node
File = string()
Reason = term()
This function works exactly the same way as analyse_to_file
except that it is asynchronous instead of synchronous. The
spawned process will link with the caller when created. If an
Error occurs while doing the cover analysis the process will
crash with the same error reason as analyse_to_file would
return.
modules() -> [Module] | {error,not_main_node}
Types:
Module = atom()
Returns a list with all modules that are currently Cover
compiled.
imported_modules() -> [Module] | {error,not_main_node}
Types:
Module = atom()
Returns a list with all modules for which there are imported
data.
imported() -> [File] | {error,not_main_node}
Types:
File = string()
Returns a list with all imported files.
which_nodes() -> [Node] | {error,not_main_node}
Types:
Node = atom()
Returns a list with all nodes that are part of the coverage
analysis. Note that the current node is not returned. This node
is always part of the analysis.
is_compiled(Module) -> {file,File} | false | {error,not_main_node}
Types:
Module = atom()
Beam = string()
Returns {file,File} if the module Module is Cover compiled, or
false otherwise. File is the .erl file used by
cover:compile_module/1,2 or the .beam file used by
compile_beam/1.
reset(Module) ->
reset() -> ok | {error,not_main_node}
Types:
Module = atom()
Resets all coverage data for a Cover compiled module Module in
the Cover database on all nodes. If the argument is omitted, the
coverage data will be reset for all modules known by Cover.
If Module is not Cover compiled, the function returns
{error,{not_cover_compiled,Module}}.
export(ExportFile)
export(ExportFile,Module) -> ok | {error,Reason}
Types:
ExportFile = string()
Module = atom()
Reason = {not_cover_compiled,Module} |
{cant_open_file,ExportFile,Reason} | not_main_node
Exports the current coverage data for Module to the file
ExportFile. It is recommended to name the ExportFile with the
extension .coverdata, since other filenames can not be read by
the web based interface to cover.
If Module is not given, data for all Cover compiled or earlier
imported modules is exported.
This function is useful if coverage data from different systems
is to be merged.
See also cover:import/1
import(ExportFile) -> ok | {error,Reason}
Types:
ExportFile = string()
Reason = {cant_open_file,ExportFile,Reason} | not_main_node
Imports coverage data from the file ExportFile created with
cover:export/1,2. Any analysis performed after this will include
the imported data.
Note that when compiling a module all existing coverage data is
removed, including imported data. If a module is already
compiled when data is imported, the imported data is added to
the existing coverage data.
Coverage data from several export files can be imported into one
system. The coverage data is then added up when analysing.
Coverage data for a module can not be imported from the same
file twice unless the module is first reset or compiled. The
check is based on the filename, so you can easily fool the
system by renaming your export file.
See also cover:export/1,2
stop() -> ok | {error,not_main_node}
Stops the Cover server and unloads all Cover compiled code.
stop(Nodes) -> ok | {error,not_main_node}
Types:
Nodes = [atom()]
Stops the Cover server and unloads all Cover compiled code on
the given nodes. Data stored in the Cover database on the remote
nodes is fetched and stored on the main node.
flush(Nodes) -> ok | {error,not_main_node}
Types:
Nodes = [atom()]
Fetch data from the Cover database on the remote nodes and
stored on the main node.
code(3erl), compile(3erl)
Personal Opportunity - Free software gives you access to billions of dollars of software at no cost. Use this software for your business, personal use or to develop a profitable skill. Access to source code provides access to a level of capabilities/information that companies protect though copyrights. Open source is a core component of the Internet and it is available to you. Leverage the billions of dollars in resources and capabilities to build a career, establish a business or change the world. The potential is endless for those who understand the opportunity.
Business Opportunity - Goldman Sachs, IBM and countless large corporations are leveraging open source to reduce costs, develop products and increase their bottom lines. Learn what these companies know about open source and how open source can give you the advantage.
Free Software provides computer programs and capabilities at no cost but more importantly, it provides the freedom to run, edit, contribute to, and share the software. The importance of free software is a matter of access, not price. Software at no cost is a benefit but ownership rights to the software and source code is far more significant.
Free Office Software - The Libre Office suite provides top desktop productivity tools for free. This includes, a word processor, spreadsheet, presentation engine, drawing and flowcharting, database and math applications. Libre Office is available for Linux or Windows.
The Free Books Library is a collection of thousands of the most popular public domain books in an online readable format. The collection includes great classical literature and more recent works where the U.S. copyright has expired. These books are yours to read and use without restrictions.
Source Code - Want to change a program or know how it works? Open Source provides the source code for its programs so that anyone can use, modify or learn how to write those programs themselves. Visit the GNU source code repositories to download the source.
Study at Harvard, Stanford or MIT - Open edX provides free online courses from Harvard, MIT, Columbia, UC Berkeley and other top Universities. Hundreds of courses for almost all major subjects and course levels. Open edx also offers some paid courses and selected certifications.
Linux Manual Pages - A man or manual page is a form of software documentation found on Linux/Unix operating systems. Topics covered include computer programs (including library and system calls), formal standards and conventions, and even abstract concepts.