```{index} single: coverage single: Devel::Cover single: cover single: HARNESS_PERL_SWITCHES ``` # 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: ```bash pperl --cpan Devel::Cover ``` They land under `~/.pperl` (or `$PPERL_HOME`, see [Installing CPAN modules](../../tutorial/cpan/installing)): 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: ```bash 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`: ```text ------------ ------ ------ ------ ------ ------ ------ 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`: ```bash 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`. ```{index} single: Devel::Cover; -select single: Devel::Cover; -ignore ``` ## 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: ```bash 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.