NAME

Test::CPAN::Health::Check::TestCoverage - Measure test suite statement coverage

SYNOPSIS

use Test::CPAN::Health::Check::TestCoverage;

my $check  = Test::CPAN::Health::Check::TestCoverage->new;
my $result = $check->run($dist);

printf "%s: %s\n", $result->status, $result->summary;

DESCRIPTION

Runs the distribution's own test suite under Devel::Cover and reports the overall statement-coverage percentage as the check score.

The check proceeds in three steps inside the distribution's root directory:

  1. Generates Makefile (via perl Makefile.PL) or Build (via perl Build.PL) if the build file is absent.

  2. Runs make test (or ./Build test) with HARNESS_PERL_SWITCHES=-MDevel::Cover and PERL5OPT=-MDevel::Cover set in the environment, causing the test harness to record coverage into cover_db/.

  3. Invokes cover -report text to generate a coverage summary, then parses the statement-coverage percentage from the Total row.

The check is skipped when any of the following apply:

  • --no-cover was passed (no_cover constructor flag).

  • Devel::Cover is not installed.

  • No .t files exist under t/.

  • Neither Makefile.PL nor Build.PL exists.

  • The cover binary cannot be located.

Score = integer part of the statement-coverage percentage. Status thresholds: pass ≥ 80, warn ≥ 60, fail otherwise.

LIMITATIONS

  • Running the test suite is slow; expect 2-5x the normal test time.

  • The check temporarily changes the process working directory to the distribution root and restores it afterwards.

  • Requires make (ExtUtils::MakeMaker dists) or a Build script (Module::Build dists).

run

PURPOSE

Execute the distribution's test suite under Devel::Cover and return the statement-coverage percentage as a 0-100 score.

API SPECIFICATION

INPUT

dist     Test::CPAN::Health::Distribution  required
context  Hashref                           optional

OUTPUT

Test::CPAN::Health::Result with check_id 'test_coverage'.

MESSAGES

Code  | Severity | Message                                          | Resolution
------+----------+--------------------------------------------------+-----------
TC001 | SKIP     | Skipped (--no-cover is set)                      | Remove --no-cover
TC002 | SKIP     | Devel::Cover is not installed                    | cpanm Devel::Cover
TC003 | SKIP     | No test files found under t/                     | Add tests
TC004 | SKIP     | No Makefile.PL or Build.PL found                 | Add build file
TC005 | SKIP     | cover binary not found                           | Install Devel::Cover
TC006 | ERROR    | Failed to run coverage check: ...                | See error detail
TC007 | ERROR    | Could not parse statement coverage from report   | Check cover output
TC008 | PASS     | Statement coverage: N%                           |
TC009 | WARN     | Statement coverage: N%                           | Add more tests
TC010 | FAIL     | Statement coverage: N%                           | Add more tests

FORMAL SPECIFICATION

-- Z schema (placeholder) --
TestCoverageOp
stmt_pct  : 0..100
score     : 0..100
-------------------------------------------------------
no_cover = true           => status = skip
Devel::Cover unavailable  => status = skip
t_files = {}              => status = skip
no build file             => status = skip
score >= 80               => status = pass
score >= 60               => status = warn
score < 60                => status = fail

SIDE EFFECTS

Runs the full test suite in a subprocess with coverage tracing enabled. Writes cover_db/ inside the distribution root. Temporarily changes and then restores the process working directory.

USAGE EXAMPLE

my $result = Test::CPAN::Health::Check::TestCoverage->new->run($dist);
printf "Statement coverage: %s\n", $result->summary;

AUTHOR

Nigel Horne, <njh at nigelhorne.com>

LICENSE AND COPYRIGHT

Copyright (C) 2025-2026 Nigel Horne.

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.