|
| php code coverage | |
Joined: 02 Aug 2007 |
Posts: 23 |
|
|
|
Posted: Thu Aug 09, 2007 7:53 pm |
|
|
|
|
|
It would be really useful for me if PhpEd included a code coverage tool for use with my unit tests. I use SimpleTest for unit tests, and, fortunately, there is no need for this to be integrated into PhpEd. However, code coverage would need to be implemented into PhpEd, since the only code coverage tools I know of utilize the Xdebug debugger instead of dbg, and I believe that you cannot have both of these installed at the same time. The profiler is the closest thing PhpEd has to a code coverage tool, and could easily be modified to be used as such. The main difference between the kind of report I would want to see with a code coverage tool and the report already displayed by the profiler, is that a code coverage report would need to show which lines were executed 0 times. You would also need to be able to specify which files it should report about. As far as I know there is no setting to make the profiler show which lines were not executed, but if there is, please enlighten me.
|
|
|
| | |
Site Admin
Joined: 13 Jul 2003 |
Posts: 8342 |
|
|
|
Posted: Fri Aug 10, 2007 12:45 pm |
|
|
|
|
|
I think it's possible with DBG.
First you'd need to add auto_append_file where you'll put the following lines in php:
<?php
$modules=array();
if (dbg_get_all_module_names($modules) >= 0) {
$mod_num = $modules['mod_no'];
$mod_name = $modules['mod_name'];
foreach($mod_num as $idx=>$mod_no) {
if ($mod_name[$idx] === __FILE__) continue;
echo $mod_name[$idx] . "\n";
$lines = array();
dbg_get_all_source_lines($mod_no, $lines);
$line_numbers = $lines['line_no'];
var_dump($line_numbers);
$profdata = array();
dbg_get_profiler_results($profdata);
$hit_count=$profdata['hit_count'];
var_dump($hit_count);
$hit_lines=$profdata['line_no'];
var_dump($hit_lines);
}
}
?> |
$line_numbers contains all the lines with code in file $mod_name[$idx]
$hit_lines contains all the lines numbers that got at least one hit
$hit_count contains hit numbers for the lines in $hit_lines
To get the results all you need is to run profiler.
|
_________________ The PHP IDE team
|
|
| | |
Joined: 02 Aug 2007 |
Posts: 23 |
|
|
|
Posted: Mon Aug 20, 2007 7:10 pm |
|
|
|
|
|
Thank you! That provides me with all the data that I need to create custom reports! I wrote a function that only displays the lines that got executed 0 times, but for some reason it sometimes does not display all of the missed lines. Here is the code:
function EchoCodeCoverageReport($runModules = null)
{
$ranModules = null;
$ranModulesIdx = 0;
$modules = array();
echo '<BR>';
if (dbg_get_all_module_names($modules) >= 0)
{
$mod_num = $modules['mod_no'];
$mod_name = $modules['mod_name'];
echo 'Code Coverage Report:<BR>';
foreach($mod_num as $idx => $mod_no)
{
if ($mod_name[$idx] === __FILE__)
{
continue;
}
if($runModules === null || in_array($mod_name[$idx], $runModules))
{
if($runModules !== null)
{
$ranModules[$ranModulesIdx] = $mod_name[$idx];
$ranModulesIdx++;
}
echo "module name: {$mod_name[$idx]}<BR>";
$lines = array();
dbg_get_all_source_lines($mod_no, $lines);
$line_numbers = $lines['line_no'];
$profdata = array();
dbg_get_profiler_results($profdata);
$hit_lines = $profdata['line_no'];
$missedLines = null;
$i = 0;
foreach($line_numbers as $value)
{
if(!in_array($value, $hit_lines))
{
$missedLines[$i] = $value;
$i++;
}
}
$numMissedLines = 0;
if($missedLines !== null)
{
$missedLines =& array_unique($missedLines);
if(!sort($missedLines))
{
echo 'Error sorting $missedLines!<BR>';
}
$numMissedLines = count($missedLines);
}
if($numMissedLines > 0)
{
echo "<font color = 'red'>";
}
else
{
echo "<font color = 'green'>";
}
echo "Missed $numMissedLines lines";
if($numMissedLines > 0)
{
echo ':<BR>';
foreach($missedLines as $missed)
{
echo $missed."<BR>";
}
}
echo "</font><BR><BR><BR><BR><BR><BR><BR><BR>";
}
}
}
if($runModules !== null)
{
if($ranModules !== null)
{
foreach($runModules as $value)
{
if(!in_array($value, $ranModules))
{
echo "<font color = 'red'>Did not run module: $value<BR></font>";
}
}
}
else
{
foreach($runModules as $value)
{
echo "Did not run module: $value<BR>";
}
}
}
}
|
You can optionally pass in an array of modules that you want it to report on exclusively. I would post an example where it does not show all the missed lines but I don't have one that I can post yet. Any ideas why it does not always show all the missed lines?
|
|
|
| | |
Joined: 02 Aug 2007 |
Posts: 23 |
|
|
|
Posted: Sun Aug 26, 2007 7:07 pm |
|
|
|
|
|
From the code I posted before, right after this:
dbg_get_all_source_lines($mod_no, $lines);
$line_numbers = $lines['line_no'];
$profdata = array();
dbg_get_profiler_results($profdata);
$hit_lines = $profdata['line_no']; |
Sometimes $hit_lines contains lines that were never hit. I will try running dmitri's code and see if the same problem occurs.
|
|
|
| | |
|
| | |
Joined: 02 Aug 2007 |
Posts: 23 |
|
|
|
Posted: Sun Aug 26, 2007 9:08 pm |
|
|
|
|
|
OK, here is a complete code example that will show you what I am talking about. This code is inside of a file named CodeCoverageTest.php
<?php
//class CodeCoverageTest
//{
function ExecuteNonQuery($sql)
{
if(mysql_query($sql) === FALSE)
{
trigger_error("MySQL Error - SQL: \"$sql\"", E_USER_ERROR);
}
}
//}
require_once('CodeCoverage.php');
CodeCoverage::EchoReport(array("C:\\www\\wwwACS\\ACSmanager\\CodeCoverageTest.php"));
?>
|
Here is the code from the file called CodeCoverage.php:
<?php
class CodeCoverage
{
function EchoReport($runModules = null)
{
$ranModules = array();
$ranModulesIdx = 0;
$modules = array();
echo '<BR>';
if (dbg_get_all_module_names($modules) >= 0)
{
$mod_num = $modules['mod_no'];
$mod_name = $modules['mod_name'];
echo 'Code Coverage Report:<BR>';
foreach($mod_num as $idx => $mod_no)
{
if ($mod_name[$idx] === __FILE__)
{
continue;
}
if($runModules === null || in_array($mod_name[$idx], $runModules))
{
if($runModules)
{
$ranModules[$ranModulesIdx] = $mod_name[$idx];
$ranModulesIdx++;
}
echo "module name: {$mod_name[$idx]}<BR>";
$lines = array();
dbg_get_all_source_lines($mod_no, $lines);
$line_numbers = $lines['line_no'];
$profdata = array();
dbg_get_profiler_results($profdata);
$hit_count=$profdata['hit_count'];
$hit_lines = $profdata['line_no'];
$missedLines = null;
$i = 0;
foreach($line_numbers as $value)
{
if(!in_array($value, $hit_lines))
{
$missedLines[$i] = $value;
$i++;
}
}
$numMissedLines = 0;
if($missedLines !== null)
{
$missedLines =& array_unique($missedLines);
if(!sort($missedLines))
{
echo 'Error sorting $missedLines!<BR>';
}
$numMissedLines = count($missedLines);
}
if($numMissedLines > 0)
{
echo "<font color = 'red'>";
}
else
{
echo "<font color = 'green'>";
}
echo "Missed $numMissedLines lines";
if($numMissedLines > 0)
{
echo ':<BR>';
foreach($missedLines as $missed)
{
echo $missed."<BR>";
}
}
echo "</font><BR><BR><BR><BR><BR><BR><BR><BR>";
}
}
}
if($runModules)
{
if($ranModules)
{
foreach($runModules as $value)
{
if(!in_array($value, $ranModules))
{
echo "<font color = 'red'>Did not run module: $value<BR></font>";
}
}
}
else
{
echo "<font color = 'red'>";
foreach($runModules as $value)
{
echo "Did not run module: $value<BR>";
}
echo "</font>";
}
}
}
}
/*
class CodeCoverage
{
function EchoReport($runModules = null)
{
$modules=array();
if (dbg_get_all_module_names($modules) >= 0)
{
$mod_num = $modules['mod_no'];
$mod_name = $modules['mod_name'];
foreach($mod_num as $idx=>$mod_no)
{
if ($mod_name[$idx] === __FILE__)
{
continue;
}
echo "<BR>{$mod_name[$idx]}<BR>";
$lines = array();
dbg_get_all_source_lines($mod_no, $lines);
$line_numbers = $lines['line_no'];
//echo "<BR>line_numbers:<BR>";
//var_dump($line_numbers);
$profdata = array();
dbg_get_profiler_results($profdata);
$hit_count=$profdata['hit_count'];
//echo "<BR>hit_count:<BR>";
//var_dump($hit_count);
$hit_lines=$profdata['line_no'];
echo "<BR>hit_lines:<BR>";
var_dump($hit_lines);
}
}
}
}
*/
?> |
Just run the file CodeCoverageTest.php with the profiler and go to the output tab. It shows 0 missed lines in CodeCoverageTest.php.
Go into the Tools->Settings and in the Debugger settings check the box that says Run profiler with debugger. Now put a break point in CodeCoverage.php on the line 37, the one that has $missedLines = null; Now run the debugger on CodeCoverageTest.php and after the break point is reached, examine the variables and you will notice that it shows lines 6 and 8 from CodeCoverageTest.php as being in the $hit_lines array and having a hit count of 1 in the $hit_count array. If you let it finish, and then look at the Profiler tab, it does not show lines 6 or 8 as having been hit. If you delete the commented out code from CodeCoverageTest.php, and run the profiler on it again, it will show line 4 as having been missed(the beginning of the if statement), but still not line 6(the trigger_error line). Please help me!
|
|
|
| | |
Site Admin
Joined: 13 Jul 2003 |
Posts: 8342 |
|
|
|
Posted: Sun Sep 02, 2007 10:12 am |
|
|
|
|
|
Quote: | Just run the file CodeCoverageTest.php with the profiler and go to the output tab. It shows 0 missed lines in CodeCoverageTest.php |
your code isn't correct.
Indeed. Take a look at the $profdata.
In its 'mod_no' array, you'll see that only idices 0, 1 and 2 relate to mod_no=1 (the file you inspect) while all the other relate to mod_no=2 which is CodeCoverage.php.
Therefore you can take only 0, 1 and 2 indices from 'line_no' and 'hit_count' (if needed) subarrays.
If you do this, you'll see that only lines 4, 13 and 14 were hit.
|
_________________ The PHP IDE team
|
|
| | |
|
| | |
Joined: 07 Jan 2015 |
Posts: 1 |
|
|
|
Posted: Wed Jan 07, 2015 12:29 am |
|
|
|
|
|
I believe that you cannot have both of these installed at the same time. The profiler is the closest thing PhpEd has to a code coverage tool, and could easily be modified to be used as such. The main difference between the kind of report I would want to see with a code coverage tool and the report already displayed by the profiler, is that a code coverage report would need to show which lines were executed 0 times. You would also need to be able to specify which files it should report about. As far as I know there is no setting to make the profiler show which lines were not executed
________________
We are the pioneers in providing toefl and exams with exam pass Download our latest passguide gmat and Florida Memorial University ccna or pass real exam of
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
All times are GMT - 5 Hours
Page 1 of 1
|
|
|
| |