Go to main content

man pages section 3: Extended Library Functions, Volume 1

Exit Print View

Updated: Wednesday, July 27, 2022
 
 

cover (3erl)

Name

cover - A Coverage Analysis Tool for Erlang

Synopsis

Please see following description for synopsis

Description

cover(3)                   Erlang Module Definition                   cover(3)



NAME
       cover - A Coverage Analysis Tool for Erlang

DESCRIPTION
       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 bot-
       tlenecks 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 com-
       mands 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 col-
       lect 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.

EXPORTS
       start() -> {ok, pid()} | {error, Reason}

              Types:

                 Reason = {already_started, pid()} | term()

              Starts the Cover server which owns the Cover internal  database.
              This  function is called automatically by the other functions in
              the module.

       local_only() -> ok | {error, too_late}

              Only support running Cover on the local node. This function must
              be  called  before  any  modules have been compiled or any nodes
              added. When running in this mode, modules will be Cover compiled
              in  a  more efficient way, but the resulting code will only work
              on the same node they were compiled on.

       start(Nodes) ->
                {ok, StartedNodes} |
                {error, not_main_node} |
                {error, local_only}

              Types:

                 Nodes = node() | [node()]
                 StartedNodes = [node()]

              Starts a Cover server on the each of given nodes, and loads  all
              cover    compiled    modules.    This    call   will   fail   if
              cover:local_only/0 has been called.

       compile(ModFiles) -> Result | [Result]

       compile(ModFiles, Options) -> Result | [Result]

       compile_module(ModFiles) -> Result | [Result]

       compile_module(ModFiles, Options) -> Result | [Result]

              Types:

                 ModFiles = mod_files()
                 Options = [option()]
                 Result = compile_result()
                 mod_files() = mod_file() | [mod_file()]
                 mod_file() = (Module :: module()) | (File :: file:filename())
                 option() =
                     {i, Dir :: file:filename()} |
                     {d, Macro :: atom()} |
                     {d, Macro :: atom(), Value :: term()} |
                     export_all
                   See compile:file/2.
                 compile_result() =
                     {ok, Module :: module()} |
                     {error, file:filename()} |
                     {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 = file:filename()
                 Options = [option()]
                 Reason = file_error()
                 Result = compile_result()
                 option() =
                     {i, Dir :: file:filename()} |
                     {d, Macro :: atom()} |
                     {d, Macro :: atom(), Value :: term()} |
                     export_all
                   See compile:file/2.
                 file_error() = eacces | enoent
                 compile_result() =
                     {ok, Module :: module()} |
                     {error, file:filename()} |
                     {error, not_main_node}

              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 = beam_mod_files()
                 Result = compile_beam_result()
                 beam_mod_files() = beam_mod_file() | [beam_mod_file()]
                 beam_mod_file() =
                     (Module :: module()) | (BeamFile :: file:filename())
                 compile_beam_result() =
                     {ok, module()} |
                     {error, BeamFile :: file:filename()} |
                     {error, Reason :: compile_beam_rsn()}
                 compile_beam_rsn() =
                     non_existing |
                     {no_abstract_code, BeamFile :: file:filename()} |
                     {encrypted_abstract_code, BeamFile :: file:filename()} |
                     {already_cover_compiled, no_beam_found, module()} |
                     {{missing_backend, module()}, BeamFile :: file:filename()} |
                     {no_file_attribute, BeamFile :: file:filename()} |
                     not_main_node

              Does the same as compile/1,2, but uses an existing .beam file as
              base, that is, the module is not compiled from source. Thus com-
              pile_beam/1 is faster than compile/1,2.

              Note  that  the  existing .beam file must contain abstract code,
              that is, 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 (that is, 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 mod-
              ule 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  cannot  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 = file:filename()
                 Reason = file_error()
                 Result = compile_beam_result()
                 compile_beam_result() =
                     {ok, module()} |
                     {error, BeamFile :: file:filename()} |
                     {error, Reason :: compile_beam_rsn()}
                 compile_beam_rsn() =
                     non_existing |
                     {no_abstract_code, BeamFile :: file:filename()} |
                     {encrypted_abstract_code, BeamFile :: file:filename()} |
                     {already_cover_compiled, no_beam_found, module()} |
                     {{missing_backend, module()}, BeamFile :: file:filename()} |
                     {no_file_attribute, BeamFile :: file:filename()} |
                     not_main_node
                 file_error() = 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, analyse_ok(), analyse_fail()} |
                  {error, not_main_node}

       analyse(Analysis) ->
                  {result, analyse_ok(), analyse_fail()} |
                  {error, not_main_node}

       analyse(Level) ->
                  {result, analyse_ok(), analyse_fail()} |
                  {error, not_main_node}

       analyse(Modules) ->
                  OneResult |
                  {result, analyse_ok(), analyse_fail()} |
                  {error, not_main_node}

       analyse(Analysis, Level) ->
                  {result, analyse_ok(), analyse_fail()} |
                  {error, not_main_node}

       analyse(Modules, Analysis) ->
                  OneResult |
                  {result, analyse_ok(), analyse_fail()} |
                  {error, not_main_node}

       analyse(Modules, Level) ->
                  OneResult |
                  {result, analyse_ok(), analyse_fail()} |
                  {error, not_main_node}

       analyse(Modules, Analysis, Level) ->
                  OneResult |
                  {result, analyse_ok(), analyse_fail()} |
                  {error, not_main_node}

              Types:

                 Analysis = analysis()
                 Level = level()
                 Modules = modules()
                 OneResult = one_result()
                 analysis() = coverage | calls
                 level() = line | clause | function | module
                 modules() = module() | [module()]
                 one_result() =
                     {ok, {Module :: module(), Value :: analyse_value()}} |
                     {ok, [{Item :: analyse_item(), Value :: analyse_value()}]} |
                     {error, {not_cover_compiled, module()}}
                 analyse_fail() = [{not_cover_compiled, module()}]
                 analyse_ok() =
                     [{Module :: module(), Value :: analyse_value()}] |
                     [{Item :: analyse_item(), Value :: analyse_value()}]
                 analyse_value() =
                     {Cov :: integer() >= 0, NotCov :: integer() >= 0} |
                     (Calls :: integer() >= 0)
                 analyse_item() =
                     (Line :: {M :: module(), N :: integer() >= 0}) |
                     (Clause ::
                          {M :: module(),
                           F :: atom(),
                           A :: arity(),
                           C :: integer() >= 0}) |
                     (Function :: {M :: module(), F :: atom(), A :: arity()})

              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 OneRe-
              sult, 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,
                           analyse_file_ok(),
                           analyse_file_fail()} |
                          {error, not_main_node}

       analyse_to_file(Modules) ->
                          Answer |
                          {result,
                           analyse_file_ok(),
                           analyse_file_fail()} |
                          {error, not_main_node}

       analyse_to_file(Options) ->
                          {result,
                           analyse_file_ok(),
                           analyse_file_fail()} |
                          {error, not_main_node}

       analyse_to_file(Modules, Options) ->
                          Answer |
                          {result,
                           analyse_file_ok(),
                           analyse_file_fail()} |
                          {error, not_main_node}

              Types:

                 Modules = modules()
                 Options = [analyse_option()]
                 Answer = analyse_answer()
                 modules() = module() | [module()]
                 analyse_option() =
                     html |
                     {outfile, OutFile :: file:filename()} |
                     {outdir, OutDir :: file:filename()}
                 analyse_answer() =
                     {ok, OutFile :: file:filename()} | {error, analyse_rsn()}
                 analyse_file_ok() = [OutFile :: file:filename()]
                 analyse_file_fail() = [analyse_rsn()]
                 analyse_rsn() =
                     {not_cover_compiled, Module :: module()} |
                     {file, File :: file:filename(), Reason :: term()} |
                     {no_source_code_found, Module :: module()}

              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 Mod-
              ule.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 da ta 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,  that  is,
              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  lat-
              ter,  two paths are examined: first the one constructed by join-
              ing ../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) -> pid()

       async_analyse_to_file(Module, OutFile) -> pid()

       async_analyse_to_file(Module, Options) -> pid()

       async_analyse_to_file(Module, OutFile, Options) -> pid()

              Types:

                 Module = module()
                 OutFile = file:filename()
                 Options = [Option]
                 Option = html
                 analyse_rsn() =
                     {not_cover_compiled, Module :: module()} |
                     {file, File :: file:filename(), Reason :: term()} |
                     {no_source_code_found, Module :: module()}

              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 of type analyse_rsn() occurs while doing the cover  analy-
              sis  the  process  will crash with the same error reason as ana-
              lyse_to_file would return.

       modules() -> [module()] | {error, not_main_node}

              Returns a list with all modules that are  currently  Cover  com-
              piled.

       imported_modules() -> [module()] | {error, not_main_node}

              Returns  a  list  with  all modules for which there are imported
              data.

       imported() -> [file:filename()] | {error, not_main_node}

              Returns a list with all imported files.

       which_nodes() -> [node()]

              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 :: file:filename()} |
                      false |
                      {error, not_main_node}

              Types:

                 Module = module()

              Returns {file, File} if the module Module is Cover compiled,  or
              false  otherwise.  File  is  the  .erl file used by compile_mod-
              ule/1,2 or the .beam file used by compile_beam/1.

       reset() -> ok | {error, not_main_node}

       reset(Module) ->
                ok |
                {error, not_main_node} |
                {error, {not_cover_compiled, Module}}

              Types:

                 Module = module()

              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(File) -> ok | {error, Reason}

       export(File, Module) -> ok | {error, Reason}

              Types:

                 File = file:filename()
                 Module = module()
                 Reason = export_reason()
                 export_reason() =
                     {not_cover_compiled, Module :: module()} |
                     {cant_open_file,
                      ExportFile :: file:filename(),
                      FileReason :: term()} |
                     not_main_node

              Exports the current coverage data for Module to the file Export-
              File. It is recommended to name the ExportFile with  the  exten-
              sion .coverdata, since other filenames cannot 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 import/1.

       import(ExportFile) -> ok | {error, Reason}

              Types:

                 ExportFile = file:filename()
                 Reason =
                     {cant_open_file, ExportFile, FileReason :: term()} |
                     not_main_node

              Imports coverage data from  the  file  ExportFile  created  with
              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 com-
              piled 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 cannot 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 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 = node() | [node()]

              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 = node() | [node()]

              Fetch  data  from  the  Cover  database  on the remote nodes and
              stored on the main node.

SEE ALSO
       code(3), compile(3)



Ericsson AB                       tools 3.5.2                         cover(3)