Module eqc_cover

This module provides a tool for measuring code coverage for Erlang code.

Copyright © Quviq AB, 2014-2017

Version: 1.42.1

Description

This module provides a tool for measuring code coverage for Erlang code.

The coverage tool works on code that has been compiled with the eqc_cover parse transform.
   17> c(test, [{parse_transform, eqc_cover}]).
   {ok,test}
   
Or using an attribute in the module:
   -compile({parse_transform, eqc_cover}).
   
To start collecting coverage data start/0 is called. After exercising the covered code, stop/0 stops data collection and returns the collected data. The common usage of collected data is to visualize it in HTML-format, using write_html/2:
   2> eqc_cover:start().
   true
   3> test:a(7).
   X: 1
   X: 2
   X: 3
   X: 4
   X: 5
   X: 6
   X: 7
   [ok,ok,ok,ok,ok,ok,ok]
   4> test:b(5, 9).
   4
   5> Data = eqc_cover:stop().
   ...
   6> eqc_cover:write_html(Data, []).
   Coverage of /Users/hans/Quviq/tmp/test.erl: 67.2%
   ok
   

The resulting HTML-output can be seen here.

Alternatively a single computation can be measured using apply/1:
   12> eqc_cover:apply(fun() -> test:a(0), test:b(2, 7) end).
   Coverage of /Users/hans/Quviq/tmp/test.erl: 51.6%
   5
   

The resulting HTML-output can be seen here.

Using stop/1 and merge_ticks/2 it is possible to tag and combine separate runs and get the aggregated coverage data with a break-down per tag. For example,
   13> eqc_cover:start().
   true
   14> [ begin test:a(X), test:b(X, 2 * X) end || X <- lists:seq(1, 100) ], ok.
   ...
   15> Run1 = eqc_cover:stop("Run 1").
   ...
   16> eqc_cover:start().
   true
   17> [ begin test:a(X), test:b(2 * X, X) end || X <- lists:seq(1, 10) ], ok.
   ...
   18> Run2 = eqc_cover:stop("Run 2").
   ...
   19> eqc_cover:write_html(eqc_cover:merge_ticks(Run1, Run2), []).
   Coverage of /Users/ulfn/work/scratch/test.erl: 95.3%
   ok

The result can be seen here.

Modules using -on_load()

Special care is needed for modules using the -on_load attribute (the most common usage is for Erlang NIFs). Due to limitations in the Erlang VM it is not possible to call the module currently being loaded using a qualified function call--this hangs the Erlang VM. This means that eqc_cover cannot collect coverage data during module loading, and thus, by default, the parse transform skips any modules using -on_load.

If there are functions in a module using -on_load that one would like to measure coverage for, it is possible to use the eqc_cover attribute to specificy precisely which functions should be cover compiled:
   -eqc_cover({cover, [a/1, b/3, g/0]}).
   
or to specify which functions should not be cover compiled:
   -eqc_cover({skip, [d/2, f/1]}).
   

Note: the parse transform checks that the function in the -on_load attribute is not among the covered functions (but it will not compute the complete call graph for this function!).

Erlang release >= R18.3.4.2

Note that you need to run an Erlang version R18.3.4.2 or later for eqc_cover to work. The coverage collection uses ets:update_counter/4. This function had initially a deadlock bug.

Data Types

html_opt()

html_opt() = {out_dir, string()} | {css_dir, string()} | {js_dir, string()}

Specify options for HTML generation. Where the HTML files should be written, and where the necessary css-files and js-files should be written.

html_opts()

html_opts() = [html_opt()]

tick()

abstract datatype: tick()

The abstract data type for a tick, used to count how many times a particular piece of code has been evaluated.

ticks()

ticks() = [tick()]

A list of ticks.

Function Index

apply/1Equivalent to apply(F, []).
apply/2 Measure coverage (and generate HTML output) for single computation.
apply/3Equivalent to apply(M, F, A, []).
apply/4Equivalent to apply(fun () -> erlang:apply(M, F, A) end, Options).
compile/1Equivalent to compile(File, []).
compile/2 Compile a module using the eqc_cover parse transform.
merge_ticks/1Equivalent to lists:foldr(fun merge_ticks/2, [], Tickss).
merge_ticks/2 Merge two sets of collected coverage ticks.
no_ticks/1 Compute an empty set of ticks for a given (list of) module(s).
start/0 Start coverage data collection (will implicity stop any ongoing data collection!).
stop/0Equivalent to stop("").
stop/1 Stop coverage data collection.
strip_tags/1 Strip (replace with "") tags from a collection of ticks.
write_html/2 Prepare and write HTML output for collected coverage data.

Function Details

apply/1

apply(F::function()) -> any()

Equivalent to apply(F, []).

apply/2

apply(F::function(), Options::html_opts()) -> any()

Measure coverage (and generate HTML output) for single computation.

Starts coverage data collection. Evaluates F, stops data collection, and generates HTML output.

apply/3

apply(M::module(), F::atom(), A::[term()]) -> any()

Equivalent to apply(M, F, A, []).

apply/4

apply(M::module(), F::atom(), A::[term()], Options::html_opts()) -> any()

Equivalent to apply(fun () -> erlang:apply(M, F, A) end, Options).

compile/1

compile(File) -> any()

Equivalent to compile(File, []).

compile/2

compile(Mod, Options) -> term()

Compile a module using the eqc_cover parse transform.

More or less equivalent to: compile:file(File, [binary, {parse_transform, eqc_cover}] ++ Options)

See compile:file/2 for more information on possible Options, and code:load_binary/3 for possible return values.

merge_ticks/1

merge_ticks(Tickss::[ticks()]) -> ticks()

Equivalent to lists:foldr(fun merge_ticks/2, [], Tickss).

merge_ticks/2

merge_ticks(Ticks1::ticks(), Ticks2::ticks()) -> ticks()

Merge two sets of collected coverage ticks.

no_ticks/1

no_ticks(Mods::module() | [module()]) -> ticks()

Compute an empty set of ticks for a given (list of) module(s).

Returns coverage data where the measured number of ticks is 0 everywhere.

start/0

start() -> true

Start coverage data collection (will implicity stop any ongoing data collection!).

stop/0

stop() -> ticks()

Equivalent to stop("").

stop/1

stop(Tag::string()) -> ticks()

Stop coverage data collection. Returns the collected coverage data tagged with Tag. When generating HTML for merged coverage data (merge_ticks/2) containing multiple tags, a break-down of the number of calls per tag will be shown.

strip_tags/1

strip_tags(Data::ticks()) -> ticks()

Strip (replace with "") tags from a collection of ticks.

write_html/2

write_html(Ticks::ticks(), Options::html_opts()) -> ok | {error, atom()}

Prepare and write HTML output for collected coverage data.

If no options are given, HTML output is written to the current directory and the css-files and js-files are also copied to the current directory. Configuration options are:


Generated by EDoc, Sep 18 2017, 16:17:38.