|
NAMETest2::Plugin::Cover - Fast and Minimal file coverage info.DESCRIPTIONThis plugin will collect minimal file coverage info, and will do so with minimal performance impact.Every time a subroutine is called this tool will do its best to find the filename the subroutine was defined in, and add it to a list. Also, anytime you attempt to open a file with "open()" or "sysopen()" the file will be added to the list. This list will be attached to a test2 event just before the test exits. In most formaters the event will only show up as a comment on STDOUT " # This test covered N source files. ". However tools such as Test2::Harness::UI can make full use of the coverage information contained in the event. NOTE: SYSOPEN HOOK DISABLEDThe sysopen hook is currently disabled because of an unknown segv error on some platforms. I am not certain if it will be enabled again. calls to subs, and calls to open are still hooked.INTENDED USE CASEThis tool is not intended to record comprehensive coverage information, if you want that use Devel::Cover.This tool is intended to obtain and maintain lists of files that were opened, or which define subs which were executed by any given test. This information is useful if you want to determine what test files to run after any given code change. The collected coverage data is contained in test2 events, if you use Test2::Harness aka "yath" then this data can be logged and consumed by other tools such as Test2::Harness::UI. PERFORMANCEUnlike tools that need to record comprehensive coverage (Devel::Cover), This module is only concerned about what files you open, or defined subs executed directly or indirectly by a given test file. As a result this module can get away with a tiny bit of XS code that only fires when a subroutine is called. Most coverage tools fire off XS for every statement.LIMITATIONSThis tool uses XS to inject a little bit of C code that runs every time a subroutine is called, or every time "open()" or "sysopen()" is called. This C code obtains the next op that will be run and tries to pull the filename from it. "eval", XS, Moose, and other magic can sometimes mask the filename, this module only makes a minimal attempt to find the filename in these cases.Originally this module only collected the filenames touched by a test. Now in addition to that data it can give you seperate lists of files where subs were called, and files that were touched via open(). Additionally the sub list includes the info about what subs were called. In all of these cases it is also possible to know what secgtions of your test called the subs or opened the files. REAL EXAMPLESThe following data was gathered using prove to run the full Moose test suite:# Prove on its own Files=478, Tests=17326, 64 wallclock secs ( 1.62 usr 0.46 sys + 57.27 cusr 4.92 csys = 64.27 CPU) # Prove with Test2::Plugin::Cover (no coverage event) Files=478, Tests=17326, 67 wallclock secs ( 1.61 usr 0.46 sys + 60.98 cusr 5.31 csys = 68.36 CPU) # Prove with Devel::Cover Files=478, Tests=17324, 963 wallclock secs ( 2.39 usr 0.58 sys + 929.12 cusr 31.98 csys = 964.07 CPU) no coverage event - No report was generated. This was done to only measure the effect of the XS that adds the data collection overhead, and not the cost of the perl code that generates the report event at the end of every test. The Moose test suite was also run using Test2::Harness aka "yath" # Without Test2::Plugin::Cover Wall Time: 62.51 seconds CPU Time: 69.13 seconds (usr: 1.84s | sys: 0.08s | cusr: 60.77s | csys: 6.44s) # With Test2::Plugin::Cover (no coverage event) Wall Time: 75.46 seconds CPU Time: 82.00 seconds (usr: 1.96s | sys: 0.05s | cusr: 72.64s | csys: 7.35s) As you can see, there is a performance hit, but it is fairly small, specially compared to Devel::Cover. This is not to say anything bad about Devel::Cover which is amazing, but a bad choice for the use case Test2::Plugin::Cover was written to address. SYNOPSISINLINEuse Test2::Plugin::Cover; ... # Arrayref of files covered so far my $covered_files = Test2::Plugin::Cover->files; COMMAND LINEYou can tell prove to use the module this way:HARNESS_PERL_SWITCHES=-MTest2::Plugin::Cover prove ... For yath: yath test --cover-files ... SUPPRESS REPORTYou can suppess the final report (only collect data, do not send the Test2 event)CLI: HARNESS_PERL_SWITCHES=-MTest2::Plugin::Cover=no_event,1 prove ... INLINE: use Test2::Plugin::Cover no_event => 1; KNOWING WHAT CALLED WHATIf you use a system like Test::Class, Test::Class::Moose, or Test2::Tools::Spec then you divide your tests into subtests (or similar). In these cases it would be nice to track what subtest (or equivelent) touched what files.There are 3 methods telated to this, "set_from()", "get_from()", and "clear_from()" which you can use to manage this meta-data: subtest foo => sub { # Note, this is a simple string, but the 'from' data can also be a data # structure. Test2::Plugin::Cover->set_from("foo"); # subroutine() from Some.pm will be recorded as having been called by 'foo'. Some::subroutine(); Test2::Plugin::Cover->clear_from(); }; Doing this manually for all blocks is not ideal, ideally you would hook your tool, such as Test::Class to call "set_from()" and "clear_from()" for you. Adding such a hook is left as an exercide to the reader, and if you make one for a popular tool please upload it to cpan and add a ticket or send an email for me to link to it here. Once you have these hooks in place the data will not only show files and subs that were called, but what called them. Please see the "set_from()" documentation for details on values. CLASS METHODS
SEE ALSODevel::Cover is by far the best and most complete coverage tool for perl. If you need comprehensive coverage use Devel::Cover. Test2::Plugin::Cover is only better for a limited use case.SOURCEThe source code repository for Test2-Plugin-Cover can be found at https://github.com/Test-More/Test2-Plugin-Cover.MAINTAINERS
AUTHORS
COPYRIGHTCopyright 2020 Chad Granum <exodist@cpan.org>.This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See http://dev.perl.org/licenses/
Visit the GSP FreeBSD Man Page Interface. |