8

I see there are some similar questions here and on http://www.perlmonks.org but I still do not get it. Imagine I have a project with a 'lib/' and a 't' directories. I run my tests with 'prove':

$ cd $PROJECT_ROOT
$ prove ./*.t

I want to get a report in html for one or more files in the 'lib/' directory. I do not want reports for the files in the 't' directory. A simple example should be enough. Thanks

pstrjds
  • 16,840
  • 6
  • 52
  • 61
Беров
  • 1,383
  • 10
  • 22

3 Answers3

7
  1. perl Makefile.PL or perl Build.PL
  2. cover -test
daxim
  • 39,270
  • 4
  • 65
  • 132
  • It is not a distributable project. there is just a directory "lib" full of *.pm and a "t" No makefiles. – Беров Jun 26 '12 at 21:35
  • 1
    @Berov, I had the same issue and Daxim's suggestion is correct. You can still add a skeleton Makefile.PL or Build.PL to your project and then get your coverage report. If it helps, I did contact the author of Devel::Cover and he confirmed that this is the way to go about it. – oalders Jun 27 '12 at 03:32
  • Amazingly this worked just fine. I created a bare-bones Makefile.PL, ran cover -test, and now I have an exhaustive set of HTML pages in folder cover_db. WHo would guess it will be so simple.... Thanks a lot. – Беров Jun 27 '12 at 11:54
  • Just to note that I found some time ago that when using Module::Build it is as easy as ```./Build testcover```. Still not sure how to get report for only a set of files in lib/ say lib/Foo/Bar/*.pm. – Беров Feb 10 '15 at 16:47
7

The proper way is to always start out with Makefile.PL/Build.PL, just as selected answer suggests. However, sometimes you are not the one who started out, so...

I used to make a fake makefile:

 % cat Makefile
 test:
      prove -Ilib -r t

The following also seems to work (w/o touching ANY files on disk):

cover -t -make 'prove -Ilib -r t; exit $?'

This only works because of how perl's system/exec handle an argument with shell metacharacters in it (; in this case) and may break in the future if cover decides to quote it more rigirously. Also it shouldn't work under windows. I wish cover had a -prove option instead.

This one still generates coverage for *.t as well as CPAN modules at nonstandard locations. This behaviour can be fixed using +select/+ignore options (see the Devel::Cover's manpage):

cover -t +select ^lib +ignore ^

So the tl;dr "magic" command is

cover -t +select ^lib +ignore ^ -make 'prove -Ilib -r t; exit $?'

EDIT The following didn't work for me - it only prints short summary:

 PERL5OPT="$PERL5OPT -MDevel::Cover" prove -Ilib -r t
 cover -t +select ^lib +ignore ^

Note that prove -MSomething applies Something to prove itself and doesn't pass it on (unlike with -I).

Dallaylaen
  • 5,268
  • 20
  • 34
  • 1
    I recommend using -make 'prove -v -Ilib; return $?;' ... rather than "echo", otherwise test failures don't cause a non-zero exit code. – Chris Lamb Sep 04 '16 at 21:45
  • Actually make 'prove -v -Ilib; exit $?;' otherwise it fails under bash - you can only `return' from a function or sourced script. It works in most other shells. – Chris Lamb Sep 06 '16 at 08:04
  • @ChrisLamb Updated according to your comments. – Dallaylaen Sep 06 '16 at 11:31
  • 1
    ^ may be special in some shells (e.g. zsh with extendedglob turned on). In this situation one has to quote it: cover -t +select '^lib' +ignore '^' ... – Slaven Rezic Nov 02 '18 at 10:11
0

Make prove run every test file with Devel::Cover activated:

$ prove --exec 'perl -MDevel::Cover=-silent,1 -Ilib' t/*.t

By default this will print the statistics after each test file. That’s why I added -silent => 1.

To print the complete statistics at the end add:

$ cover -summary
Daniel Böhmer
  • 14,463
  • 5
  • 36
  • 46