Hello, dear esteemed monks!

I have made a test script that makes cover -t include untested modules into the summary, thus lowering the overall coverage level and the developer's exaggerated ego.

Not even sure how I didn't come up with something like that earlier. So... Here it is:

dallaylaen/todo.t

UPDATE The script doesn't spawn more processes now and runs on Windows. No warnings issued.

#!/usr/bin/env perl # This script tests nothing (except the fact that modules load w/o war +nings). # However, it tries to load them all. # This means that untested modules would also be included into # code coverage summary, lowering total coverage to its actual value. # I.e. having a well-covered module and a totally uncovered one will r +esult # in 50% coverage which is probably closer to truth. use strict; use warnings; use Test::More; use FindBin qw($Bin); use File::Basename qw(dirname); use File::Find; # Try to load EVERY module in t/../lib my $path = dirname($Bin)."/lib"; my @files; find (sub { /\.pm$/ or return; -f $File::Find::name or return; $File::Find::name =~ s#^\Q$path\E[/\\]##; push @files, $File::Find::name; }, $path); # Save warnings for later my @warn; foreach my $file (@files) { # This sub suppresses warnings but saves them for later display local $SIG{__WARN__} = sub { push @warn, "$file: $_[0]"; }; ok ( eval{ require $file }, "$file loaded" ) or diag "Error in $file: $@"; }; # print report foreach (@warn) { diag "WARN: $_"; }; # If you are concerned about cover -t, then probably warnings during l +oad # are not OK with you is( scalar @warn, 0, "No warnings during load" ); done_testing;

Suggestions, improvements are welcome!

Replies are listed 'Best First'.
Re: A unit-test script that causes remorse
by stevieb (Canon) on Sep 05, 2016 at 15:01 UTC
    "Suggestions, improvements are welcome!"

    Instead of shelling out to get the file names:

    use File::Find::Rule; my $path = 'lib'; my @files = File::Find::Rule->file() ->name('*.pm') ->in($path);

      Thanks, added it. I try to require File::Find::Rule and fall back to shell in case it's not there.

        Good idea. Take a look at Module::Load. I've used it in some of my distributions where I've needed to dynamically load modules by module or file name based on conditions and whether they are available. May be of use to you here.

        Regarding the sub redefined issue, you're not copying a module to a new name without changing the package name within for testing are you? I can't trigger this unless I copy one module, as-is, to another module name. eg: copy lib/Module.pm to lib/ModuleWithoutTests.pm without changing the package name within the copied file.

        Granted though, I only spent a couple of minutes playing so I very well could be overlooking something...

        This might break WIN. Better to require it or to use a more simple version of file finding that is core.

      Runs on stock File::Find now, Windows included, and no more warnings. Thanks again.