Question

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?

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top