5

I'm having issues merging data for coverage on Perl scripts and modules.. Running Devel::Cover individually works just fine, but when I try to combine the data I lose statistics for just the Perl script not the module..

Let me explain..

I have a directory tree that looks like so..

Code_Coverage_Test
 |
 |---->lib
 |
 |---->t
 |

Inside the root Code_Coverage_Test directory I have the Build.pl file that builds the tests for the module and script that kickoff two other scripts that automate some commands for me..

./Build.pl

#!/usr/bin/perl -w

use strict;
use Module::Build;

my $buildTests = Module::Build->new(
        module_name             => 'testPMCoverage',
        license                 => 'perl',
        dist_abstract           => 'Perl .pm Test Code Coverage',
        dist_author             => 'me@myEmail.com',
        build_requires  => {
           'Test::More' => '0.10',
        },

);

$buildTests->create_build_script();

./startTests.sh

#!/bin/sh

cd t
./doPMtest.sh
./doPLtest.sh

cd ../

perl Build testcover

Inside the lib dir I have the files I'm trying to run Code coverage on..

lib/testPLCoverage.pl

#!/usr/bin/perl -w

use strict;

print "Ok!";

lib/testPMCoverage.pm

use strict;
use warnings;
package testPMCoverage;

sub hello {
    return "Hello";
}

sub bye {
    return "Bye";
}


1;

In the t dir I have my .t test file for the module and 2 scripts that kickoff the tests for me.. Both of which are called by the startTests.sh in the root directory

t/testPMCoverage.t

#!/usr/bin/perl -w


use strict;
use Test::More;

require_ok( 'testPMCoverage' );

my $test = testPMCoverage::hello();
is($test, "Hello", "hello() test");

done_testing();

t/doPLtest.sh

#!/bin/sh

#Test 1
cd ../
cd lib
perl -MDevel::Cover=-db,../cover_db testPLCoverage.pl

t/doPMtest.sh

#!/bin/bash

cd ../
perl Build.pl
perl Build test

The issue I'm running into is that when the doPLtests.sh script runs, I get coverage data, no problem..

---------------------------- ------ ------ ------ ------ ------ ------ ------
File                           STMT   Bran   Cond    Sub    pod   Time  total
---------------------------- ------ ------ ------ ------ ------ ------ ------
testPLCoverage.pl             100.0    n/a    n/a  100.0    n/a  100.0  100.0
Total                         100.0    n/a    n/a  100.0    n/a  100.0  100.0
---------------------------- ------ ------ ------ ------ ------ ------ ------

However, when the doPMtest.sh script finishes and the startTests.sh script initiates the Build testcover command I lose that data along the way and I get these messages ...

Reading database path/Code_Coverage_Tests/cover_db
Devel::Cover: Warning: can't open testPLCoverage.pl for MD5 digest: No such file or directory
Devel::Cover: Warning: can't locate structure for statement in testPLCoverage.pl
Devel::Cover: Warning: can't locate structure for subroutine in testPLCoverage.pl
Devel::Cover: Warning: can't locate structure for time in testPLCoverage.pl

..and somehow I lose the data

---------------------------- ------ ------ ------ ------ ------ ------ ------
File                           STMT   Bran   Cond    Sub    pod   Time  total
---------------------------- ------ ------ ------ ------ ------ ------ ------
blib/lib/testPMCoverage.pm     87.5    n/a    n/a   75.0    0.0  100.0   71.4
testPLCoverage.pl               n/a    n/a    n/a    n/a    n/a    n/a    n/a
Total                          87.5    n/a    n/a   75.0    0.0  100.0   71.4
---------------------------- ------ ------ ------ ------ ------ ------ ------

How can I combine the Perl module and Perl script tests to get valid code coverage in ONE file?

drthvdr
  • 95
  • 5

1 Answers1

5

Perl doesn't store the full path to the files it uses. If it finds the file via a relative path then only the relative path is stored. You can see this in the paths perl shows in the warning and error messages from those files.

When Devel::Cover deals with files it uses the path given by perl. You can see this in the reports from Devel::Cover where you have testPLCoverage.pl and blib/lib/testPMCoverage.pm.

What this means for you in practice is that whenever you put coverage into a coverage DB you should ensure that you are doing it from the same directory, so that Devel::Cover can match and locate the files in the coverage DB.

I think this is the problem you are hitting.

My suggestion is that in t/doPLtest.sh you don't cd into lib. You can run something like:

perl -Mblib -MDevel::Cover=-db,../cover_db lib/testPLCoverage.pl

(As an aside, why is that file in lib?)

I think that would mean that Devel::Cover would be running from the project root in each case and so should allow it to match and find the files.

pjcj
  • 421
  • 2
  • 3
  • Moving the files out of the lib directory worked.. However, to my understanding and according to the [tutorials](http://stackoverflow.com/questions/533553/perl-build-unit-testing-code-coverage-a-complete-working-example) I've seen, to use `Devel::Cover`to see coverage data for Perl modules I need to use `Module::Build`, which requires the modules to be in a [lib](http://stackoverflow.com/questions/21919588/how-do-i-change-the-default-modulebuild-testmore-directory-from-lib-to-s) directory... I understand you wrote `Devel::Cover` (great work btw), is there a different way to go about this? – drthvdr Apr 01 '14 at 13:41
  • You don't *need* to use Module:Build, but using it or Makefile.PL is a good idea for developing Perl modules in general. So yes, the modules should go into the lib/ directory, but scripts shouldn't. You would generally put them into a bin/ or scripts/ directory. – pjcj Apr 03 '14 at 21:09