protected function tearDown() { xdebug_stop_code_coverage(false); $this->clearEntity($this->method); xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE); parent::tearDown(); }
/** * Stop collection of code coverage information. * * @return array */ public function stop() { // @codeCoverageIgnoreStart $codeCoverage = xdebug_get_code_coverage(); xdebug_stop_code_coverage(); return $codeCoverage; // @codeCoverageIgnoreEnd }
public static function stopCodeCoverage() { if (function_exists('xdebug_stop_code_coverage') && self::$coverageStopped === false) { self::$coverageStopped = xdebug_stop_code_coverage(false); return self::$coverageStopped; } return; }
public static function pauseCodeCoverageAnalysis() { if (false === self::isCodeCoverageAnalysisRunning()) { return; } self::collectCodeCoverageReport(); xdebug_stop_code_coverage(false); self::$m_isCodeCoverageAnalysisRunning = false; }
/** * 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)); }
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)); } }
/** * 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 static function stop($reportDir = null) { if ($reportDir !== null) { self::initialize($reportDir); } if (function_exists('xdebug_start_code_coverage')) { $userStory = self::getUserStoryFromFile(); self::updateCodeCoverageReports($userStory); // some session handlers, close() for example, will be called after main script finished executing, so if we call CodeCoverage::stop() // and xdebug is stopped then it will be implossible to get code coverage stats for such session handlers. xdebug_stop_code_coverage(true); } self::generateHtmlReports($reportDir); }
/** * 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; }
/** * 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 endDebug() { if (defined('SH_DEBUG_VERIFY_FOLDER') && is_dir(SH_DEBUG_VERIFY_FOLDER)) { if (defined('SH_DEBUG_COVERAGE_PAGE')) { $linker = sh_linker::getInstance(); if (file_exists(SH_DEBUG_COVERAGE_PAGE)) { include SH_DEBUG_COVERAGE_PAGE; } else { $coverage = array(); } $all_elements = debug_get_coverage($coverage); $linker->helper->writeArrayInFile(SH_DEBUG_COVERAGE_PAGE, "coverage", $all_elements); xdebug_stop_code_coverage(); } } }
/** * 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; }
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(); }
/** * 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); }
/** * Stop collection of code coverage information. * * @return array */ public function stop() { $data = xdebug_get_code_coverage(); xdebug_stop_code_coverage(); return $this->cleanup($data); }
$data[$file] = $lines; } else { foreach ($lines as $line => $flag) { if (!isset($data[$file][$line]) || $flag > $data[$file][$line]) { $data[$file][$line] = $flag; } } } } } } echo serialize($data); exit; } if (isset($_SERVER['HTTP_X_ENABLE_COVERAGE']) && isset($_SERVER['HTTP_X_TEST_SESSION_ID']) && extension_loaded('xdebug')) { // Register a shutdown function that stops code coverage and stores the coverage of the current // request register_shutdown_function(function () { $data = xdebug_get_code_coverage(); xdebug_stop_code_coverage(); $coverageDir = sys_get_temp_dir() . '/behat-coverage'; if (is_dir($coverageDir) || mkdir($coverageDir, 0775, true)) { $filename = sprintf('%s/%s.%s.cov', $coverageDir, md5(uniqid('', true)), $_SERVER['HTTP_X_TEST_SESSION_ID']); file_put_contents($filename, serialize($data)); } }); // Start code coverage xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE); } // Return false from the router to serve the requested file as is return false;
function main() { $files = $this->getFilenames(); $this->log("Setting up coverage database for " . count($files) . " files"); $props = new Properties(); foreach ($files as $file) { $fullname = $file['fullname']; $filename = $file['key']; $props->setProperty($filename, serialize(array('fullname' => $fullname, 'coverage' => array()))); } $dbfile = new PhingFile($this->database); $props->store($dbfile); $this->project->setProperty('coverage.database', $dbfile->getAbsolutePath()); foreach ($files as $file) { $fullname = $file['fullname']; xdebug_start_code_coverage(XDEBUG_CC_UNUSED); Phing::__import($fullname, $this->classpath); $coverage = xdebug_get_code_coverage(); xdebug_stop_code_coverage(); CoverageMerger::merge($this->project, array($coverage)); } }
/** * Stops the code coverage * * @return array results */ public static function coverageStop() { if (!extension_loaded("xdebug")) { return null; } $tCoverageData = xdebug_get_code_coverage(); xdebug_stop_code_coverage(); $tFinal = ["files" => [], "total" => ["coveredLines" => 0, "totalLines" => 0]]; foreach ($tCoverageData as $tPath => $tLines) { $tFileCoverage = ["path" => $tPath, "coveredLines" => array_keys($tLines), "totalLines" => FileSystem::getFileLineCount($tPath)]; $tFinal["files"][] = $tFileCoverage; $tFinal["total"]["coveredLines"] += count($tFileCoverage["coveredLines"]); $tFinal["total"]["totalLines"] += $tFileCoverage["totalLines"]; } $tFinal["total"]["percentage"] = $tFinal["total"]["coveredLines"] * 100 / $tFinal["total"]["totalLines"]; return $tFinal; }
/** * Stops the current code coverage analyzation and dumps a nice report depending on the reporter that was passed to start() * * @return void */ function report($output = true) { $manager =& CodeCoverageManager::getInstance(); if (!$manager->groupTest) { $testObjectFile = $manager->__testObjectFileFromCaseFile($manager->testCaseFile, $manager->appTest); if (!file_exists($testObjectFile)) { trigger_error('This test object file is invalid: ' . $testObjectFile); return; } $dump = xdebug_get_code_coverage(); xdebug_stop_code_coverage(); $coverageData = array(); foreach ($dump as $file => $data) { if ($file == $testObjectFile) { $coverageData = $data; break; } } if (empty($coverageData) && $output) { echo 'The test object file is never loaded.'; } $execCodeLines = $manager->__getExecutableLines(file_get_contents($testObjectFile)); $result = ''; switch (get_class($manager->reporter)) { case 'CakeHtmlReporter': $result = $manager->reportCaseHtmlDiff(@file($testObjectFile), $coverageData, $execCodeLines, $manager->numDiffContextLines); break; case 'CLIReporter': $result = $manager->reportCaseCli(@file($testObjectFile), $coverageData, $execCodeLines, $manager->numDiffContextLines); break; default: trigger_error('Currently only HTML and CLI reporting is supported for code coverage analysis.'); break; } } else { $testObjectFiles = $manager->__testObjectFilesFromGroupFile($manager->testCaseFile, $manager->appTest); foreach ($testObjectFiles as $file) { if (!file_exists($file)) { trigger_error('This test object file is invalid: ' . $file); return; } } $dump = xdebug_get_code_coverage(); xdebug_stop_code_coverage(); $coverageData = array(); foreach ($dump as $file => $data) { if (in_array($file, $testObjectFiles)) { $coverageData[$file] = $data; } } if (empty($coverageData) && $output) { echo 'The test object files are never loaded.'; } $execCodeLines = $manager->__getExecutableLines($testObjectFiles); $result = ''; switch (get_class($manager->reporter)) { case 'CakeHtmlReporter': $result = $manager->reportGroupHtml($testObjectFiles, $coverageData, $execCodeLines, $manager->numDiffContextLines); break; case 'CLIReporter': $result = $manager->reportGroupCli($testObjectFiles, $coverageData, $execCodeLines, $manager->numDiffContextLines); break; default: trigger_error('Currently only HTML and CLI reporting is supported for code coverage analysis.'); break; } } if ($output) { echo $result; } }
/** * Stop collection of code coverage information. * * @return array */ public function stop() { $codeCoverage = xdebug_get_code_coverage(); xdebug_stop_code_coverage(); return $codeCoverage; }
/** * Stop gathering coverage data, saving it for later reporting */ public function stop_instrumentation() { if (extension_loaded("xdebug")) { $lastcoveragedata = xdebug_get_code_coverage(); // Get last instrumentation coverage data xdebug_stop_code_coverage(); // Stop code coverage $this->coverageData = self::merge_coverage_data($this->coverageData, $lastcoveragedata); // Append lastcoveragedata $this->logger->debug("[moodle_coverage_recorder::stopInstrumentation()] Code coverage: " . print_r($this->coverageData, true), __FILE__, __LINE__); return true; } else { $this->logger->critical("[moodle_coverage_recorder::stopInstrumentation()] Xdebug not loaded.", __FILE__, __LINE__); } return false; }
/** * Stops code coverage. */ public static function stop() { if (self::isCovering()) { xdebug_stop_code_coverage(); } }
protected function addUncoveredFilesInformation($uncovered_files) { $total_coverage = array(); foreach ($uncovered_files as $file => $status) { if ($status && file_exists($file)) { xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE); include_once $file; $coverage = xdebug_get_code_coverage(); xdebug_stop_code_coverage(); foreach ($coverage as $filename => $cov) { if ($this->_uncoveredFiles[$filename]) { foreach ($cov as $cov_line => $cov_line_flag) { if (is_array($cov_line_flag)) { /* foreach(array_keys($cov_line_flag) as $flag){ $cov[$cov_line][$flag] = 0; } */ $cov[$cov_line] = array(); for ($i = 1; $i <= count($cov_line_flag); $i++) { $cov[$cov_line][$i] = 0; } } elseif ($cov_line_flag > 0) { $cov[$cov_line] = -1; } $total_coverage[$filename] = $cov; $this->_uncoveredFiles[$filename] = false; } } } } } return $total_coverage; }
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); }
/** * Run the tests * * This method will run the tests with the correct Reporter. It will run * grouped tests if asked to and filter results. It also has support for * running coverage report. * */ public function run() { $testGroup = $this->testGroup; if (PHP_SAPI === 'cli') { require_once dirname(__FILE__) . '/DoctrineTest/Reporter/Cli.php'; $reporter = new DoctrineTest_Reporter_Cli(); $argv = $_SERVER['argv']; array_shift($argv); $options = $this->parseOptions($argv); } else { require_once dirname(__FILE__) . '/DoctrineTest/Reporter/Html.php'; $options = $_GET; if (isset($options['filter'])) { if (!is_array($options['filter'])) { $options['filter'] = explode(',', $options['filter']); } } if (isset($options['group'])) { if (!is_array($options['group'])) { $options['group'] = explode(',', $options['group']); } } $reporter = new DoctrineTest_Reporter_Html(); } //replace global group with custom group if we have group option set if (isset($options['group'])) { $testGroup = new GroupTest('Doctrine Custom Test', 'custom'); foreach ($options['group'] as $group) { if (isset($this->groups[$group])) { $testGroup->addTestCase($this->groups[$group]); } else { if (class_exists($group)) { $testGroup->addTestCase(new $group()); } else { die($group . " is not a valid group or doctrine test class\n "); } } } } if (isset($options['ticket'])) { $testGroup = new GroupTest('Doctrine Custom Test', 'custom'); foreach ($options['ticket'] as $ticket) { $class = 'Doctrine_Ticket_' . $ticket . '_TestCase'; $testGroup->addTestCase(new $class()); } } $filter = ''; if (isset($options['filter'])) { $filter = $options['filter']; } //show help text if (isset($options['help'])) { $availableGroups = sort(array_keys($this->groups)); echo "Doctrine test runner help\n"; echo "===========================\n"; echo " To run all tests simply run this script without arguments. \n"; echo "\n Flags:\n"; echo " -coverage will generate coverage report data that can be viewed with the cc.php script in this folder. NB! This takes time. You need xdebug to run this\n"; echo " -group <groupName1> <groupName2> <className1> Use this option to run just a group of tests or tests with a given classname. Groups are currently defined as the variable name they are called in this script.\n"; echo " -filter <string1> <string2> case insensitive strings that will be applied to the className of the tests. A test_classname must contain all of these strings to be run\n"; echo "\nAvailable groups:\n " . implode(', ', $availableGroups) . "\n"; die; } //generate coverage report if (isset($options['coverage'])) { /* * The below code will not work for me (meus). It would be nice if * somebody could give it a try. Just replace this block of code * with the one below * define('PHPCOVERAGE_HOME', dirname(dirname(__FILE__)) . '/vendor/spikephpcoverage'); require_once PHPCOVERAGE_HOME . '/CoverageRecorder.php'; require_once PHPCOVERAGE_HOME . '/reporter/HtmlCoverageReporter.php'; $covReporter = new HtmlCoverageReporter('Doctrine Code Coverage Report', '', 'coverage2'); $includePaths = array('../lib'); $excludePaths = array(); $cov = new CoverageRecorder($includePaths, $excludePaths, $covReporter); $cov->startInstrumentation(); $ret = $testGroup->run($reporter, $filter); $cov->stopInstrumentation(); $cov->generateReport(); $covReporter->printTextSummary(); return $ret; */ xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE); $ret = $testGroup->run($reporter, $filter); $result['coverage'] = xdebug_get_code_coverage(); xdebug_stop_code_coverage(); file_put_contents(dirname(__FILE__) . '/coverage/coverage.txt', serialize($result)); require_once dirname(__FILE__) . '/DoctrineTest/Coverage.php'; $coverageGeneration = new DoctrineTest_Coverage(); $coverageGeneration->generateReport(); return $ret; // */ } if (array_key_exists('only-failed', $options)) { $testGroup->onlyRunFailed(true); } $result = $testGroup->run($reporter, $filter); global $startTime; $endTime = time(); $time = $endTime - $startTime; if (PHP_SAPI === 'cli') { echo "\nTests ran in " . $time . " seconds and used " . memory_get_peak_usage() / 1024 . " KB of memory\n\n"; } else { echo "<p>Tests ran in " . $time . " seconds and used " . memory_get_peak_usage() / 1024 . " KB of memory</p>"; } return $result; }
/** * @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; }
/** * 保存已经收集到的数据们 * @param $code_coverage_key */ public function collect($code_coverage_key) { // 捞一份旧的 $codeinfos = array(); $cg = xdebug_get_code_coverage(); xdebug_stop_code_coverage(); if (file_exists($this->collectDir . "/{$code_coverage_key}.php")) { $codeinfos = (include $this->collectDir . "/{$code_coverage_key}.php"); } foreach ($cg as $path => $lines) { if (!isset($codeinfos[$path])) { $codeinfos[$path] = array(); } foreach ($lines as $line => $status) { if (isset($codeinfos[$path][$line]) && $codeinfos[$path][$line] == 1 || $status == 1) { $codeinfos[$path][$line] = 1; } else { $codeinfos[$path][$line] = $status; } } } if (is_array($codeinfos)) { $content = var_export($codeinfos, 1); // 加锁形式的写入,性能会有下降的哦 file_put_contents($this->collectDir . "/{$code_coverage_key}.php", "<?php return {$content};", LOCK_EX); } }