Coverage: which code your tests run#
A coverage report answers a question the debugger cannot: which statements, branches, conditions and subroutines a test run never reached. pperl runs Devel::Cover, the coverage tool perl5 uses, and reports the same numbers perl5 does.
Installing Devel::Cover#
The compiled part of Devel::Cover is built into pperl. Its Perl modules and its cover command come from CPAN:
pperl --cpan Devel::Cover
They land under ~/.pperl (or $PPERL_HOME, see Installing CPAN modules): the modules in ~/.pperl/lib/perl5, which pperl searches without being told, and the command as ~/.pperl/bin/cover.
If PERL5LIB points at a perl5 tree that already has Devel::Cover, pperl --cpan finds that copy, reports the module as up to date and installs nothing. Run it with PERL5LIB unset. Keep the perl5 tree’s copy out of covered runs, too: pperl needs its own.
Measuring a program#
Load Devel::Cover with -M, then run cover in the same directory:
pperl -MDevel::Cover yourprog.pl
pperl ~/.pperl/bin/cover
The run collects into cover_db/ in the current directory. cover prints a summary per file and writes an HTML report to cover_db/coverage.html. For a program prog.pl that calls one of the two subs of its module lib/Shape.pm:
------------ ------ ------ ------ ------ ------ ------
File stmt bran cond sub time total
------------ ------ ------ ------ ------ ------ ------
lib/Shape.pm 50.0 50.0 33.3 50.0 0.0 45.4
prog.pl 100.0 n/a n/a 100.0 100.0 100.0
Total 81.8 50.0 33.3 75.0 100.0 70.0
------------ ------ ------ ------ ------ ------ ------
Every option of Devel::Cover and of cover works as under perl5: cover -report text for a plain-text report, -report json for JSON, cover -delete to start over. A pod column appears when Pod::Coverage is installed, as it does under perl5.
Measuring a test suite#
HARNESS_PERL_SWITCHES adds -MDevel::Cover to every test the harness starts. Run prove itself under pperl, so that the tests run under pperl too; -S finds prove on the PATH:
HARNESS_PERL_SWITCHES=-MDevel::Cover=-ignore,^t/ pperl -S prove -l t
pperl ~/.pperl/bin/cover
-ignore,^t/ keeps the test files themselves out of the report. prove --exec pperl does not apply HARNESS_PERL_SWITCHES, under perl5 either, nor -l; with --exec, put both in the command itself: prove --exec "pperl -Ilib -MDevel::Cover=-ignore,^t/" t.
Choosing what is reported#
Devel::Cover leaves out modules that belong to the installation, ~/.pperl/lib/perl5 among them. The check it uses for that does not know PPERL5LIB or PPERL_HOME, so with either set, modules from those trees are covered and reported like your own code. In that setup, choose the files with -select and -ignore, both regular expressions over file names:
pperl -MDevel::Cover=-select,^lib/,-ignore,^t/ yourprog.pl
Speed#
While Devel::Cover collects, pperl does not compile loops to machine code: compiled code would run past the counters Devel::Cover reads. A covered run is therefore as fast as pperl’s interpreter, not as fast as a normal pperl run. A run without -MDevel::Cover is unaffected.