Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use PHP_CodeCoverage without PHPUnit?

For some reasons, I'd like to analyze the code coverage of my application with PHP_CodeCoverage, but not by using PHP unit (with manual testing).

I know how to use XDebug on the long run (across multiple requests, by keeping the code coverage analysis into the shared memory). Building simple XML files such as clover.xml (or any other format) after some tests is not difficult with the output of XDebug (it is a simple associative array and it is documented).

Is there a way to instruct PHP_CodeCoverage to use clover.xml (or another file format) so as to generate the HTML report (which is very good). Or do you know a simple hack that would rely on PHP_CodeCoverage internal function to deal directly with the output of XDebug so as to generate the HTML report.

like image 418
Benjamin BALET Avatar asked Oct 20 '22 01:10

Benjamin BALET


2 Answers

After some experiments, this is what I've developed.

First, you need to use PHP_CodeCoverage as described into the documentation. After the end of the coverage code analysis, you can serialize the PHP_CodeCoverage object into a temporary file. Here I am using uniqid so as to have a unique name for each request. You need to instrument your code with the snippet below into a common script of your application (the first part where the request starts, and the second part where it ends):

require_once "phpcov/vendor/autoload.php";
$filter = new PHP_CodeCoverage_Filter();
$filter->addDirectoryToBlacklist(__DIR__ . "/phpcov");
$token = uniqid();
$coverage = new PHP_CodeCoverage(null, $filter);
$coverage->start($token);

//Do something

$coverage->stop();

$s = serialize($coverage);
file_put_contents('tmp/' . $token, $s);

When my testing campaign is finnished, I can merge all the temporary files into the same PHP_CodeCoverage_Report_HTML:

require_once "phpcov/vendor/autoload.php";
$coverage = new PHP_CodeCoverage();

$files = glob('tmp/*');
foreach($files as $file) {
    $s = file_get_contents($file);
    $data = unserialize($s);
    $coverage->merge($data);
}

$writer = new PHP_CodeCoverage_Report_HTML;
$writer->process($coverage, 'report-coverage');

Don't forget to set PHP_CodeCoverage_Filter so as to eliminate all unwanted scripts of your framework and of the many libraries you may use.

If you are using CodeIgniter, you can rely on hooks as I did for my project.

like image 191
Benjamin BALET Avatar answered Nov 01 '22 15:11

Benjamin BALET


So you if you don't want to use php_unit or php_CodeCoverage just to get code coverage information I realized that to write it myself was pretty easy. To capture the data into multiple files (one file for each run) nicely was about 50 lines of code and to later merge all the code coverage runs was about 100 lines of code (I could get it down to 80 - it's really not that hard). The 100 lines of code outputs a very pretty document with covered lines in a pastel green, lines of code not covered in a pink background and lines that don't matter (such as comments and whitespace) are white background.

The code is quite simple and easy to read and can be found here: https://github.com/jlgtechnologies/php_code_coverage/blob/master/php_code_coverage_report.php

I added an lgpl but if you want a different license let me know on github.

Just include php_code_coverage.php at the top of one of the files you want covered and optionally call the white-list filter if you only want to do code coverage on certain files.

Then call the other file from your browser to get the report: php_code_coverage_report.php

The files end up in /tmp/ so if you changed your code or want to reset the coverage you just do rm -f /tmp/phpcc_*

You will need the xdebug module installed into php (wasn't hard - lots of instructions on the web) but you won't need any other libraries.

Just read the code - it's pretty self explanatory and simple. Only took an hour or so to write it and get it working

like image 30
gr5 Avatar answered Nov 01 '22 16:11

gr5