/** * Get code coverage with Xdebug * @link http://www.xdebug.org/docs/code_coverage * * @return array filename as key and codes as array values */ public static function get_code_coverage() { if (!function_exists('xdebug_get_code_coverage')) { return array('xdebug is not installed, no code coverage'); } $coverage = xdebug_get_code_coverage(); foreach ($coverage as $file => $line) { if (!file_exists($file)) { continue; } /** $file_contents = file($file); $code = ''; foreach ($line as $lineNumber => $int1) { if (isset($file_contents[$lineNumber-1])) { $code.= sprintf('%4d: ',$lineNumber); $code.= $file_contents[$lineNumber-1]; } } $coverage[$file] = highlight_string($code, true); /**/ $key = preg_replace('/\\/vagrant\\//', '', $file); unset($coverage[$file]); $coverage[$key] = $file; } if (array_key_exists('cc_sort', $_GET)) { ksort($coverage); } return $coverage; }
function debug_get_coverage($oldCoverage = array()) { $array = xdebug_get_code_coverage(); $ret = $oldCoverage; if (!is_array($array)) { return $ret; } foreach ($array as $file => $views) { if (substr(basename($file), 0, -8) == SH_DEBUG_COVERAGE_CLASS) { $fileContents = file($file); foreach ($fileContents as $num => $lineContent) { $lineContent = trim($lineContent); if (isset($views[$num]) || $lineContent == '<?php') { $previousLine = LINE_USED; $ret[$file]['l_' . ($num + 1)] += LINE_USED; // Used line } elseif ($lineContent == '' || $lineContent == '}') { if ($previousLine) { $ret[$file]['l_' . ($num + 1)] = $previousLine; } } else { $previousLine = LINE_UNUSED; } } } } return $ret; }
/** * Launches a test module for web inspection of results * @param string $module * @return boolean */ function WebLauncher($module) { jf::$ErrorHandler->UnsetErrorHandler(); $this->LoadFramework(); self::$TestSuite = new \PHPUnit_Framework_TestSuite(); self::$TestFiles[] = $this->ModuleFile($module); self::$TestSuite->addTestFile(self::$TestFiles[0]); $result = new \PHPUnit_Framework_TestResult(); $listener = new TestListener(); $result->addListener($listener); $Profiler = new Profiler(); if (function_exists("xdebug_start_code_coverage")) { xdebug_start_code_coverage(); } self::$TestSuite->run($result); if (function_exists("xdebug_start_code_coverage")) { $Coverage = xdebug_get_code_coverage(); } else { $Coverage = null; } $Profiler->Stop(); $listener->Finish(); $this->OutputResult($result, $Profiler, $Coverage); return true; }
/** * Stop collection of code coverage information. * * @return array */ public function stop() { // @codeCoverageIgnoreStart $codeCoverage = xdebug_get_code_coverage(); xdebug_stop_code_coverage(); return $codeCoverage; // @codeCoverageIgnoreEnd }
static function onShutdown() { if (self::$tests_report_path) { file_put_contents(self::$tests_report_path, json_encode(array('file_name' => self::$tested_file_name, 'assertions' => self::$assertions_count, 'errors' => self::$errors_count, 'error_message' => self::$error_message, 'time' => microtime(true) - self::$start_time)) . PHP_EOL, FILE_APPEND); } if (self::$coverage_file_path) { file_put_contents(self::$coverage_file_path, json_encode(xdebug_get_code_coverage()) . PHP_EOL, FILE_APPEND); } }
/** * Paints the end of a group test. Will paint the page * footer if the stack of tests has unwound. * @param string $test_name Name of test that is ending. * @param integer $progress Number of test cases ending. */ function paintGroupEnd($test_name) { if (extension_loaded('xdebug')) { $this->code_coverage = xdebug_get_code_coverage(); xdebug_stop_code_coverage(); ksort($this->code_coverage); } HtmlReporter::paintGroupEnd($test_name); }
function save_coverage_data($test_id) { $data = xdebug_get_code_coverage(); xdebug_stop_code_coverage(); if (!is_dir($GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'])) { mkdir($GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'], 0777, true); } $file = $GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'] . '/' . $test_id . '.' . md5(uniqid(rand(), true)); echo "Saving coverage data to {$file}...\n"; file_put_contents($file, serialize($data)); }
/** * shutdown function to generate coverage */ function kataCodeCoverage() { $data = xdebug_get_code_coverage(XDEBUG_CC_DEAD_CODE | XDEBUG_CC_UNUSED); ksort($data); foreach ($data as $name => &$lines) { if (substr($name, 0, strlen(ROOT)) != ROOT) { continue; } $temp = explode(DS, $name); if (in_array('lib', $temp)) { continue; } $shortFile = array_pop($temp); $shortDir = array_pop($temp); $shortName = $shortDir . DS . $shortFile; if ($shortDir == 'config' || $shortName == 'webroot' . DS . 'index.php') { continue; } echo '<br /><h2>' . $shortName . '</h2>'; if ($shortDir == 'lang') { echo 'skipping... ' . $shortDir . ' <br />'; continue; } $file = file($name); $tdCell = '<td style="border:1px solid red;padding:2px;">'; echo '<table style="min-width:100%;border:1px solid red;color:black;background-color:#e8e8e8;border-collapse:collapse;">'; foreach ($file as $lineno => $line) { $count = 0; if (isset($lines[$lineno + 1])) { $count = $lines[$lineno + 1]; } if ($count > 2) { $count = 3; } echo '<tr>' . $tdCell . $lineno . '</td>' . $tdCell . '<tt'; switch ($count) { case 0: echo ' style="color:#c0c0c0;"'; break; case 1: echo ''; break; case 2: case 3: echo ' style="color:#ffe0e0;"'; break; } echo '>' . h($line) . '</tt></td></tr>'; } echo '</table>'; } unset($lines); echo '</table>'; }
public function stopCodeCoverage() { //echo "stopCodeCoverage called...\n"; if (extension_loaded('xdebug')) { $data = xdebug_get_code_coverage(); xdebug_stop_code_coverage(); //echo "xdebug_stop_code_coverage called...\n"; global $CDASH_COVERAGE_DIR; $file = $CDASH_COVERAGE_DIR . DIRECTORY_SEPARATOR . md5($_SERVER['SCRIPT_FILENAME']); file_put_contents($file . '.' . md5(uniqid(rand(), true)) . '.' . get_class(), serialize($data)); } }
function save_coverage() { $coverage_filename = sys_get_temp_dir() . "/adminer_coverage.ser"; $coverage = unserialize(file_get_contents($coverage_filename)); foreach (xdebug_get_code_coverage() as $filename => $lines) { foreach ($lines as $l => $val) { if (!$coverage[$filename][$l] || $val > 0) { $coverage[$filename][$l] = $val; } } file_put_contents($coverage_filename, serialize($coverage)); } }
/** * Stops code coverage. * * @return array The collected coverage */ public function stop() { $data = xdebug_get_code_coverage(); xdebug_stop_code_coverage($this->_config['cleanup']); $result = []; foreach ($data as $file => $coverage) { foreach ($coverage as $line => $value) { if ($line && $value !== -2) { $result[$file][$line - 1] = $value === -1 ? 0 : $value; } } } return $result; }
public function stopCoverage() { $cov = xdebug_get_code_coverage(); $this->filter($cov); $data = new CoverageDataHandler($this->log); chdir($this->root); $data->write($cov); unset($data); // release sqlite connection xdebug_stop_code_coverage(); // make sure we wind up on same current working directory, otherwise // coverage handler writer doesn't know what directory to chop off chdir($this->root); }
/** * Stop collection of code coverage information and store it in Sqlite3. * * @return array */ public function stop() { $cov = xdebug_get_code_coverage(); xdebug_stop_code_coverage(); if (!isset($this->root)) { $this->root = getcwd(); } $dataHandler = new DataHandler(self::SQLITE_DB); chdir($this->root); $dataHandler->write($cov); $cleanData = $this->cleanup($dataHandler->read()); unset($dataHandler); // release sqlite connection return $cleanData; }
public function save() { $data = xdebug_get_code_coverage(); $files = $this->src->getData(); foreach ($data as $fileName => $lines) { if (!$this->isFileInDir($fileName)) { continue; } $file = $files->find($fileName); foreach ($lines as $lineNo => $isUsed) { $file->addUsedLine($lineNo - 1); } } $this->src->saveData($files); }
/** * Takes an instance of an object (usually a Collection object) containing test * instances. Attaches code coverage filtering to test cases. * * @see lithium\test\filter\Coverage::collect() * @param object $report Instance of Report which is calling apply. * @param array $tests The test to apply this filter on * @param array $options Options for how code coverage should be applied. These options are * also passed to `Coverage::collect()` to determine how to aggregate results. See * the documentation for `collect()` for further options. Options affecting this * method are: * -'method': The name of method to attach to, defaults to 'run'. * @return object|void Returns the instance of `$tests` with code coverage analysis * triggers applied. */ public static function apply($report, $tests, array $options = array()) { $defaults = array('method' => 'run'); $options += $defaults; $m = $options['method']; $filter = function ($self, $params, $chain) use($report, $options) { xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE); $chain->next($self, $params, $chain); $results = xdebug_get_code_coverage(); xdebug_stop_code_coverage(); $report->collect(__CLASS__, array($self->subject() => $results)); }; $tests->invoke('applyFilter', array($m, $filter)); return $tests; }
function shutdown() { $File = "/watt/coverage.txt"; $fh = fopen($File, 'a') or die("Error: cant open file"); //$oldcov = unserialize(file_get_contents($File)); $cov = xdebug_get_code_coverage(); $appname = $_GET['wattappname']; $traceid = $_GET['watttraceid']; $requestid = $_GET['wattrequestid']; $linktype = $_GET['wattlinktype']; foreach ($cov as $fname => $fcov) { foreach ($fcov as $fline => $value) { $line = $appname . "," . $traceid . "," . $requestid . "," . $fname . "," . $fline . ",\n"; fputs($fh, $line) or die("error writing"); } } }
/** * Collects information about code coverage. * @return array */ private static function collectXdebug() { $positive = $negative = array(); foreach (xdebug_get_code_coverage() as $file => $lines) { if (!file_exists($file)) { continue; } foreach ($lines as $num => $val) { if ($val > 0) { $positive[$file][$num] = $val; } else { $negative[$file][$num] = $val; } } } return array($positive, $negative); }
/** * Takes an instance of an object (usually a Collection object) containing test * instances. Attaches code coverage filtering to test cases. * * @see lithium\test\filter\Coverage::collect() * @param object $report Instance of Report which is calling apply. * @param array $tests The test to apply this filter on * @param array $options Options for how code coverage should be applied. These options are * also passed to `Coverage::collect()` to determine how to aggregate results. See * the documentation for `collect()` for further options. Options affecting this * method are: * -'method': The name of method to attach to, defaults to 'run'. * @return object Returns the instance of `$tests` with code coverage analysis * triggers applied. */ public static function apply($report, $tests, array $options = array()) { $defaults = array('method' => 'run'); $options += $defaults; if (!function_exists('xdebug_start_code_coverage')) { $msg = "Xdebug not installed. Please install Xdebug before running code coverage."; throw new RuntimeException($msg); } $filter = function ($self, $params, $chain) use($report, $options) { xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE); $chain->next($self, $params, $chain); $results = xdebug_get_code_coverage(); xdebug_stop_code_coverage(); $report->collect(__CLASS__, array($self->subject() => $results)); }; $tests->invoke('applyFilter', array($options['method'], $filter)); return $tests; }
/** * Saves information about code coverage. Do not call directly. * @return void * @internal */ public static function save() { $f = fopen(self::$file, 'a+'); flock($f, LOCK_EX); fseek($f, 0); $coverage = @unserialize(stream_get_contents($f)); foreach (xdebug_get_code_coverage() as $filename => $lines) { foreach ($lines as $num => $val) { if (empty($coverage[$filename][$num]) || $val > 0) { $coverage[$filename][$num] = $val; // -1 => untested; -2 => dead code } } } ftruncate($f, 0); fwrite($f, serialize($coverage)); fclose($f); }
function paintFooter($test_name) { if (extension_loaded('xdebug')) { $this->coverage = xdebug_get_code_coverage(); xdebug_stop_code_coverage(); } $colour = $this->getFailCount() + $this->getExceptionCount() > 0 ? "red" : "green"; print "<div style=\""; print "padding: 8px; margin-top: 1em; background-color: {$colour}; color: white;"; print "\">"; print $this->getTestCaseProgress() . "/" . $this->getTestCaseCount(); print " test cases complete:\n"; print "<strong>" . $this->getPassCount() . "</strong> passes, "; print "<strong>" . $this->getFailCount() . "</strong> fails and "; print "<strong>" . $this->getExceptionCount() . "</strong> exceptions."; print "</div>\n"; $this->paintCoverage(); print "</body>\n</html>\n"; }
function save_code_coverage() { $coverage_directory = "/home/alice/twfy-coverage/"; if (!file_exists($coverage_directory)) { mkdir($coverage_directory, 0777, TRUE); } global $coverage_identifier; $output_filename = $coverage_directory . $coverage_identifier; $coverage_data = xdebug_get_code_coverage(); $fp = fopen($output_filename, "w"); fwrite($fp, $output_filename . "\n"); foreach ($coverage_data as $filename => $line_map) { fwrite($fp, $filename . "\n"); foreach ($line_map as $line_number => $number_of_uses) { fwrite($fp, " " . $line_number . ": " . $number_of_uses . "\n"); } } fclose($fp); xdebug_stop_code_coverage(); }
/** * Saves information about code coverage. Do not call directly. * @return void * @internal */ public static function save() { flock(self::$file, LOCK_EX); fseek(self::$file, 0); $coverage = @unserialize(stream_get_contents(self::$file)); // @ file may be empty foreach (xdebug_get_code_coverage() as $filename => $lines) { if (!file_exists($filename)) { continue; } foreach ($lines as $num => $val) { if (empty($coverage[$filename][$num]) || $val > 0) { $coverage[$filename][$num] = $val; // -1 => untested; -2 => dead code } } } ftruncate(self::$file, 0); fwrite(self::$file, serialize($coverage)); fclose(self::$file); }
function argumentDecode($nTimes, $aArgs) { global $timer; global $trips; $objResponse = new xajaxResponse(); if ($nTimes < $trips) { $nTimes += 1; $objResponse->script('xajax_argumentDecode(' . $nTimes . ', jsArray);'); $objResponse->assign('submittedDiv', 'innerHTML', 'Working...'); $objResponse->append('submittedDiv', 'innerHTML', print_r($aArgs, true)); } else { $objResponse->assign('submittedDiv', 'innerHTML', 'Done'); ob_start(); var_dump(xdebug_get_code_coverage()); $objResponse->append('submittedDiv', 'innerHTML', ob_get_clean()); } $timer->stop(); $objResponse->call('accumulateTime', $timer->timeElapsed()); $objResponse->call('printTime'); return $objResponse; }
/** * @param array $codeCoverageInformation * @param boolean $filterTests * @return array */ public static function getFilteredCodeCoverage(array $codeCoverageInformation, $filterTests = TRUE) { if (self::$filter) { list($isFilteredCache, $missedFiles) = self::getFileCodeCoverageDisposition($codeCoverageInformation, $filterTests); foreach ($codeCoverageInformation as $k => $test) { foreach (array_keys($test['files']) as $file) { if (isset($isFilteredCache[$file]) && $isFilteredCache[$file]) { unset($codeCoverageInformation[$k]['files'][$file]); } } foreach (array_keys($test['dead']) as $file) { if (isset($isFilteredCache[$file]) && $isFilteredCache[$file]) { unset($codeCoverageInformation[$k]['dead'][$file]); } } foreach (array_keys($test['executable']) as $file) { if (isset($isFilteredCache[$file]) && $isFilteredCache[$file]) { unset($codeCoverageInformation[$k]['executable'][$file]); } } } if (self::$addUncoveredFilesFromWhitelist) { foreach (self::$whitelistedFiles as $whitelistedFile) { if (!isset(self::$coveredFiles[$whitelistedFile]) && !self::isFiltered($whitelistedFile, $filterTests, TRUE)) { if (file_exists($whitelistedFile)) { xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE); include_once $whitelistedFile; $coverage = xdebug_get_code_coverage(); xdebug_stop_code_coverage(); foreach ($coverage as $file => $fileCoverage) { if (!in_array($file, self::$whitelistedFiles) || isset(self::$coveredFiles[$file])) { continue; } foreach ($fileCoverage as $line => $flag) { if ($flag > 0) { $fileCoverage[$line] = -1; } } $codeCoverageInformation[] = array('test' => NULL, 'files' => array($file => $fileCoverage)); self::addCoveredFile($file); } } } } } } return $codeCoverageInformation; }
public function addNoCoverageFiles() { echo "Adding files with no coverage information\n"; // Start by pruning out files we already have information about $sql = 'SELECT * FROM files WHERE issource = 1'; $result = $this->db->query($sql); while ($res = $result->fetchArray(SQLITE3_ASSOC)) { $key = array_search($res['path'], $this->files); if (isset($this->files[$key])) { unset($this->files[$key]); } } $codepath = $this->codepath; spl_autoload_register(function ($class) use($codepath) { $file = str_replace(array('\\', '_'), DIRECTORY_SEPARATOR, $class); if (file_exists($codepath . DIRECTORY_SEPARATOR . $file . '.php')) { include $codepath . DIRECTORY_SEPARATOR . $file . '.php'; return true; } if ($file = stream_resolve_include_path($file . '.php')) { include $file; return true; } $fake_class = '<?php class ' . $class . ' {}'; $fake_class_file = tempnam(sys_get_temp_dir(), 'pyrus_tmp'); file_put_contents($fake_class_file, $fake_class); include $fake_class_file; unlink($fake_class_file); return true; }); foreach ($this->files as $file) { if (empty($file)) { continue; } echo "{$file}\n"; $id = $this->addFile($file, 1); // Figure out of the file has been already inclduded or not $included = false; $relative_file = substr($file, strlen($this->codepath . DIRECTORY_SEPARATOR), -4); // We need to try a few things here to actually find the correct class // Foo/Bar.php may mean Foo_Bar Foo\Bar or PEAR2\Foo\Bar $class = str_replace('/', '_', $relative_file); $ns_class = str_replace('/', '\\', $relative_file); $pear2_class = 'PEAR2\\' . $ns_class; $classes = array_merge(get_declared_classes(), get_declared_interfaces()); if (in_array($class, $classes) || in_array($ns_class, $classes) || in_array($pear2_class, $classes)) { $included = true; } // Get basic coverage information on the file if ($included === false) { xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE); include $file; $data = xdebug_get_code_coverage(true); $this->lines[$id] = $data[$file]; } else { /* * @TODO files that already have been loaded need to have * their missing coverage lines added too */ } } echo "Done\n"; }
/** * Saves information about code coverage. * @return void */ public static function saveCoverage() { $file = dirname(__FILE__) . '/coverage.tmp'; $coverage = @unserialize(file_get_contents($file)); $root = realpath(dirname(__FILE__) . '/../../Nette') . DIRECTORY_SEPARATOR; foreach (xdebug_get_code_coverage() as $filename => $lines) { if (strncmp($root, $filename, strlen($root))) { continue; } foreach ($lines as $num => $val) { if (empty($coverage[$filename][$num]) || $val > 0) { $coverage[$filename][$num] = $val; // -1 => untested; -2 => dead code } } } file_put_contents($file, serialize($coverage)); }
/** * Paints coverage report if enabled. * @param string $group Name of test or other label. * @access public */ function paintGroupEnd($group) { $this->group = ""; $cc = ""; if ($this->cc) { if (extension_loaded('xdebug')) { $arrfiles = xdebug_get_code_coverage(); xdebug_stop_code_coverage(); $thisdir = dirname(__FILE__); $thisdirlen = strlen($thisdir); foreach ($arrfiles as $index => $file) { if (substr($index, 0, $thisdirlen) === $thisdir) { continue; } $lcnt = 0; $ccnt = 0; foreach ($file as $line) { if ($line == -2) { continue; } $lcnt++; if ($line == 1) { $ccnt++; } } if ($lcnt > 0) { $cc .= round($ccnt / $lcnt * 100, 2) . '%'; } else { $cc .= "0.00%"; } $cc .= "\t" . $index . "\n"; } } } $this->listener->write('{status:"coverage",message:"' . EclipseReporter::escapeVal($cc) . '"}'); }
/** * Runs a TestCase. * * @param PHPUnit_Framework_Test $test */ public function run(PHPUnit_Framework_Test $test) { PHPUnit_Framework_Assert::resetCount(); $error = FALSE; $failure = FALSE; $this->startTest($test); $errorHandlerSet = FALSE; if ($this->convertErrorsToExceptions) { $oldErrorHandler = set_error_handler(array('PHPUnit_Util_ErrorHandler', 'handleError'), E_ALL | E_STRICT); if ($oldErrorHandler === NULL) { $errorHandlerSet = TRUE; } else { restore_error_handler(); } } if (self::$xdebugLoaded === NULL) { self::$xdebugLoaded = extension_loaded('xdebug'); self::$useXdebug = self::$xdebugLoaded; } $useXdebug = self::$useXdebug && $this->collectCodeCoverageInformation && !$test instanceof PHPUnit_Extensions_SeleniumTestCase; if ($useXdebug) { xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE); } PHPUnit_Util_Timer::start(); try { $test->runBare(); } catch (PHPUnit_Framework_AssertionFailedError $e) { $failure = TRUE; } catch (Exception $e) { $error = TRUE; } $time = PHPUnit_Util_Timer::stop(); if ($useXdebug) { $codeCoverage = xdebug_get_code_coverage(); xdebug_stop_code_coverage(); $this->appendCodeCoverageInformation($test, $codeCoverage); } if ($errorHandlerSet === TRUE) { restore_error_handler(); } $test->addToAssertionCount(PHPUnit_Framework_Assert::getCount()); if ($error === TRUE) { $this->addError($test, $e, $time); } else { if ($failure === TRUE) { $this->addFailure($test, $e, $time); } } $this->endTest($test, $time); }
private static function collectCodeCoverageReport() { self::$m_codeCoverageReport = xdebug_get_code_coverage(); }
<?php /* to use this in your server, edit /etc/php.ini and add this file to auto_append_file then add coverage-prepend.php to auto_prepend_file. requires xdebug to be installed. */ if (defined('COVERAGE_ON')) { /* create this file, then chown it so Apache can edit it. */ $stats_file = '/var/log/php-coverage'; foreach (xdebug_get_code_coverage() as $k => $v) { $str = $k . ' | '; $str .= join(',', array_keys($v)); file_put_contents($stats_file, $str . "\n", FILE_APPEND); } }