Skip to content
Permalink
Browse files

Add PCOV support (#396)

  • Loading branch information...
trejjam authored and milo committed Feb 2, 2019
1 parent 2cd6160 commit a49594af93adf453df272d4b1b96238216b9b1ce
Showing with 53 additions and 7 deletions.
  1. +1 βˆ’1 composer.json
  2. +3 βˆ’3 readme.md
  3. +34 βˆ’0 src/CodeCoverage/Collector.php
  4. +6 βˆ’1 src/Runner/CliTester.php
  5. +1 βˆ’0 src/tester.php
  6. +4 βˆ’2 tests/CodeCoverage/Collector.phpt
  7. +4 βˆ’0 tests/Runner/PhpInterpreter.phpt
@@ -2,7 +2,7 @@
"name": "nette/tester",
"description": "Nette Tester: enjoyable unit testing in PHP with code coverage reporter. 🍏🍏🍎🍏",
"homepage": "https://tester.nette.org",
"keywords": ["testing", "unit", "nette", "phpunit", "code coverage", "xdebug", "phpdbg", "clover", "assertions"],
"keywords": ["testing", "unit", "nette", "phpunit", "code coverage", "xdebug", "phpdbg", "pcov", "clover", "assertions"],
"license": ["BSD-3-Clause", "GPL-2.0", "GPL-3.0"],
"authors": [
{
@@ -32,7 +32,7 @@ composer require nette/tester --dev
Alternatively, you can download the [tester.phar](https://github.com/nette/tester/releases) file.

Nette Tester 2.0 requires PHP 5.6 and supports PHP up to 7.3. The 2.1 version requires PHP 7.1.
Collecting and processing code coverage information depends on Xdebug, or PHPDBG.
Collecting and processing code coverage information depends on Xdebug or PCOV extension, or PHPDBG SAPI.


Writing Tests
@@ -149,8 +149,8 @@ tester -j 1
```

How do you find code that is not yet tested? Use Code-Coverage Analysis. This feature
requires you have installed [Xdebug](https://xdebug.org/) in `php.ini`, or you are
using PHPDBG. This will generate nice HTML report in `coverage.html`.
requires you have installed [Xdebug](https://xdebug.org/) or [PCOV](https://github.com/krakjoe/pcov)
extension, or you are using PHPDBG SAPI. This will generate nice HTML report in `coverage.html`.

```
tester . -c php.ini --coverage coverage.html --coverage-src /my/source/codes
@@ -16,6 +16,7 @@
class Collector
{
public const
ENGINE_PCOV = 'PCOV',
ENGINE_PHPDBG = 'PHPDBG',
ENGINE_XDEBUG = 'Xdebug';
@@ -29,6 +30,7 @@ class Collector
public static function detectEngines(): array
{
return array_filter([
extension_loaded('pcov') ? self::ENGINE_PCOV : null,
defined('PHPDBG_VERSION') ? self::ENGINE_PHPDBG : null,
extension_loaded('xdebug') ? self::ENGINE_XDEBUG : null,
]);
@@ -53,6 +55,11 @@ public static function start(string $file, string $engine): void
self::$file = fopen($file, 'c+');
switch ($engine) {
case self::ENGINE_PCOV:
\pcov\start();
self::$collector = 'collectPCOV';
break;
case self::ENGINE_PHPDBG:
phpdbg_start_oplog();
self::$collector = 'collectPhpDbg';
@@ -109,6 +116,33 @@ public static function save(): void
}
/**
* Collects information about code coverage.
*/
private static function collectPCOV(): array
{
$positive = $negative = [];
\pcov\stop();
foreach (\pcov\collect() 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 [$positive, $negative];
}
/**
* Collects information about code coverage.
*/
@@ -12,6 +12,7 @@
use Tester\CodeCoverage;
use Tester\Dumper;
use Tester\Environment;
use Tester\Helpers;
/**
@@ -229,7 +230,7 @@ private function prepareCodeCoverage(Runner $runner): string
{
$engines = $this->interpreter->getCodeCoverageEngines();
if (count($engines) < 1) {
throw new \Exception("Code coverage functionality requires Xdebug extension or phpdbg SAPI (used {$this->interpreter->getCommandLine()})");
throw new \Exception("Code coverage functionality requires Xdebug or PCOV extension or PHPDBG SAPI (used {$this->interpreter->getCommandLine()})");
}
file_put_contents($this->options['--coverage'], '');
@@ -238,6 +239,10 @@ private function prepareCodeCoverage(Runner $runner): string
$runner->setEnvironmentVariable(Environment::COVERAGE, $file);
$runner->setEnvironmentVariable(Environment::COVERAGE_ENGINE, $engine = reset($engines));
if ($engine === CodeCoverage\Collector::ENGINE_PCOV && count($this->options['--coverage-src'])) {
$runner->addPhpIniOption('pcov.directory', Helpers::findCommonDirectory($this->options['--coverage-src']));
}
echo "Code coverage by $engine: $file\n";
return $file;
}
@@ -26,6 +26,7 @@
require __DIR__ . '/Framework/Dumper.php';
require __DIR__ . '/Framework/DataProvider.php';
require __DIR__ . '/Framework/TestCase.php';
require __DIR__ . '/CodeCoverage/Collector.php';
require __DIR__ . '/CodeCoverage/PhpParser.php';
require __DIR__ . '/CodeCoverage/Generators/AbstractGenerator.php';
require __DIR__ . '/CodeCoverage/Generators/HtmlGenerator.php';
@@ -9,9 +9,11 @@ use Tester\FileMock;
require __DIR__ . '/../bootstrap.php';
$engines = CodeCoverage\Collector::detectEngines();
$engines = array_filter(CodeCoverage\Collector::detectEngines(), function (string $engine) {
return $engine !== CodeCoverage\Collector::ENGINE_PCOV; // PCOV needs system pcov.directory INI to be set
});
if (count($engines) < 1) {
Tester\Environment::skip('Requires Xdebug or phpdbg SAPI.');
Tester\Environment::skip('Requires Xdebug or PHPDB SAPI.');
}
$engine = reset($engines);
@@ -25,4 +25,8 @@ if (extension_loaded('xdebug')) {
Assert::contains(Tester\CodeCoverage\Collector::ENGINE_XDEBUG, $engines);
$count++;
}
if (extension_loaded('pcov')) {
Assert::contains(Tester\CodeCoverage\Collector::ENGINE_PCOV, $engines);
$count++;
}
Assert::count($count, $engines);

0 comments on commit a49594a

Please sign in to comment.
You can’t perform that action at this time.